ホーム > iPhone
iPhoneのアーカイブ
FingerPKというゲームをリリースしたり、Help meをアップデートしたり
初めてゲームアプリを作ってみました。
対戦型のサッカーPKゲームです。(コンピューター対戦とかは無い)
二ヶ月前くらい前に @LuckOfWise さんと東京に行ったときに思いついたアプリ。
本当はAndroidとiOSで対戦できるようにしたかったけど思ったより敷居が高かったので保留。
1台でも遊べるけど、2台のiOS機器があるとより楽しめます。
よろしければどうぞ。
Finger PK(無料)
そして、もう一本は初めて作ったiOSアプリ「Help me」をアップデートしました。
地味にダウンロードされ続けているこのアプリ。
デザインからソースまで1から作り直しました。昔のソースはね。。。ほら。w
機能も追加しましたよ。
- Facebookへ緊急事態を知らせるメッセージを投稿する機能
- iOS標準のメーラーでの送信機能
緊急メールをサーバー側で送っていたのですが(1タップで送信するため) 、送信元を偽装していたので届かない事も多かったみたいで。
タップ数は増えるけど標準メーラーで送信できるようにしました。
もう一つの機能は日本でもFacebookユーザーが増えてきたので、ウォールに投稿すれば友人が助けてくれるんじゃないかと思って。
詳しくは下記からどうぞ。
iOS 標準アプリの時計の様に指定時間・曜日にメッセージを通知する方法
iOS標準の時計アプリでは時間と曜日を指定して、その時間にアラームを通知する方法があります。
今回は同じような方法でメッセージを通知する方法がないかなぁ〜と思って調べました。(仕事で使う予定があるから)
やりたいことはこんな感じ
- アプリでメッセージを通知したい曜日と時間を設定
- アプリを終了(バックグラウンドでもOK)
- 指定した曜日と時間になったらメッセージを通知
- 「OK」ボタンを押下するとアプリが起動
で調べたけど、メッセージを通知するのはUIRemoteNotification、UILocalNotificationというのを使うらしい。
UIRemoteNotificationはサーバーを立ててそこからメッセージを一括送信する場合などに使うみたい。
UILocalNotificationは指定時間にメッセージを表示する方法で端末内で完結できる。
ということで、今回はUILocalNotificationを使う。
で今回最も悩んだのが、UILocalNotificationに指定曜日にメッセージを通知する方法。
repeatIntervalというプロパティがあるのですが、毎日とか毎時ならこれでOKなんだけど、指定曜日(毎週月・火・木)となると、できないみたい。(多分)
で色々と調べた結果、簡単に設定できるプロパティはないのではないかと。。。
Notification系のものは内部にカレンダー形式でローカル通知の予定を登録しているようなので、ぐるぐる回しながら自分で曜日を判断して登録するという方法を取りました。困ったときは回せば良い。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [[UIApplication sharedApplication] cancelAllLocalNotifications]; NSInteger repeartCount = 7; for (NSInteger i = 0; i < repeartCount; i++) { date = [today dateByAddingTimeInterval:i * 24 * 60 * 60]; dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:date]; if ([selectedWeek containsObject:[NSNumber numberWithInteger:dateComponents.weekday - 1]]) { // Adding the local notification. dateString = [NSString stringWithFormat:@"%@ %@", [dateFormat stringFromDate:date], [timeFormat stringFromDate:notificationTime]]; if ([today compare:[format dateFromString:dateString]] == NSOrderedAscending) { notification.fireDate = [format dateFromString:dateString]; notification.timeZone = [NSTimeZone localTimeZone]; notification.alertBody = [NSString stringWithFormat:@"Notify:%@", dateString]; notification.soundName = UILocalNotificationDefaultSoundName; notification.alertAction = @"Open"; notification.repeatCalendar [[UIApplication sharedApplication] scheduleLocalNotification:notification]; } } |
1行目の「[[UIApplication sharedApplication] cancelAllLocalNotifications]」で現在登録されているメッセージ通知のカレンダーを全クリアします。これは後で何度もこの処理を実行するので重複してローカル通知が登録されないようにするためです。
3行目で繰り返しを行う日数を今日から含めて指定します。今回は今日から7日間に指定しました。最大で7日分のローカル通知の予定を登録します。UILocalNotificationは最大で60前後のカレンダーが登録できるみたいです。
5行目から指定回数分ループで回します。
6行目で日付を取得して、9行目でその日付の曜日を取得してその曜日が登録すべき曜日かを判断しています。selectedWeekには日曜日〜土曜日までを0〜6の数値で保持しているので、containsObjectで配列内の要素の存在確認を行っています。
登録すべき曜日であれば、11〜22行目の処理によってメッセージ通知の登録が行われていきます。
ちなみに15行目では登録する日付が過去日付ならば登録をスキップしています。今日が月曜日の12時でローカル通知を月曜日の6持で設定すると過去日付になるので1回目の通知が即座に表示されてしまうので。
でこの方法だと登録されているローカル通知を全部通知し終わってしまうと通知されなくなります。
そこで、UILocalNotificationのデリゲートを使って起動の度に上記の処理を実行します。
デリゲートはメッセージ通知のアクションボタンが押下されてアプリが起動される度に呼び出されるみたい。
1 2 3 4 5 6 7 8 9 10 11 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UILocalNotification *notification; notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; if (notification) { [LocalNotificationManager addLocalNotification]; } return YES; } |
でまずは、アプリが完全に終了(バックグラウンドで動作していない)している場合には、「application:didFinishLaunchingWithOptions:」から起動されます。
4〜8行目でこの起動がNotificationによるものなのか判断してもし、Notificationによるものだったら7行目でローカル通知の処理を実行しています。
1 2 3 4 5 | - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [LocalNotificationManager addLocalNotification]; } |
でもう一個のデリゲートが「application:didReceiveLocalNotification:」でこちらはバックグラウンドでアプリが動作していた場合に呼ばれます。あとは先程と同様にローカル通知の処理を実行して完了です。
これでローカル通知が指定した曜日の時間に起動され、通知によってアプリが起動された場合には再度起動した日から7日間のスケジュールが再登録されるようになりました。
まあただこの方法だと、ローカル通知で呼び出しても起動されなかった場合には登録した通知を全て表示し終わった場合には通知されなくなりますね。
アプリ起動時に毎回ローカル通知の登録を行っても、やっぱり同じでアプリ起動もローカル通知による起動もまったく行われなかった場合にはいつか通知されなくなります。
永久的にローカル通知を表示することはできるのかな?(良い方法があればダレか教えて。)
ということで今回の確認に使ったサンプルをgithubに上げておきます。
もうちょっと使いやすい様にクラス化すればよかったんですけどね。。。それはオイオイということで。
iOSのUILabelで文字列の縦位置を調整する方法
UIButtonなどのtitleLabelに文字列を設定した場合に上にずれることがあります。
UILabelで以前に同様の問題に悩まされてゴリゴリとやっていたのですが、少しだけシンプルな方法を見つけたのでメモしておきます。
IBを使ってUIButtonを配置して「Type=Cutom」として、Fontを「ヒラギノ角ゴ ProN W6」で指定すると下記の通り上にずれます。
ここで真っ先に考えるのがtitleLabelの縦位置(Vertical Alignment)をCenterに!っと考えるんですけど、無いんですよね。。。そんなプロパティ。(確かKeynoteでも縦位置の調整が無いんだよな。。。Apple的には縦位置は上揃えなんでしょうか。。。)
UIButtonの中身の位置を微調整する
そこで中身を下記のように微調整すると縦位置を強制的に変更することができます。
この方法の問題は文字サイズを変更した場合に再度微調整する必要があります。
1 | button.contentEdgeInsets = UIEdgeInsetsMake(8.0f, 0.0f, 0.0f, 0.0f); |
フォントの種類を変更する
で、もう1つの方法がtitleLabelのフォント種類を「Helvetica-Bold」で指定する方法。
こっちは「Helvetica-Bold」で指定しても表示するときは「ヒラギノ」になっているような気がする。。。
1 | button.titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:18.0f]; |
これらの方法は最もベストでは無い気がしますが現状ではベターではある気がします。
できれば、UIButtonやUILabelにverticalAlignのプロパティを準備してほしいですけどね。。。
ホーム > iPhone
- 検索
- フィード
- メタ情報







