StaticCellsのローカライズ

storyboardでStaticCellsのテーブル作ってたんだけど、ローカライズがめんどい。
とりあえず以下のようなコードで対応しているけど、もっとスマートな方法は無いかなぁ…。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *titles = @[NSLocalizedString(@"TitleIndex_One", nil),
                        NSLocalzedString(@"TitleIndex_Two", nil)];
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    cell.textLabel.text = titles[indexPath.row];
    return cell;
}

というかStaticCells使わずにDynamicPrototypesにしておけば良かった。

Build Configuration毎でinfo.plistの内容を変更する

かんばんわ。
アルザです。

info.plistの内容をビルド毎に変更したい場面があったため調査してみました。
今回は「UIFileSharingEnabled (Application supports iTunes file sharing)」のtrue/falseをビルド毎に切り替えてみます。
試してないけど、URLスキーム等の文字列なんかも切り替える事ができると思う。

XcodeのProject設定の Build Setting を眺めていると「Info.plist Preprocessor Prefix File」という項目を発見。
ここにInfo.plist用のヘッダファイルを指定すればInfo.plist内でdefineを使う事ができそうです。

▼Info.plist Preprocessor Prefix Fileの作成
まずはInfo.plist用のヘッダファイルを作成。
ここではInfoDebugPreprocessor.hとします。

作成したらInfoDebugPreprocessor.hにdefineを定義しておきましょう。

#define DEBUG_FILE_SHARING_ENABLED true

今のところこんな感じ。

▼Build Settingsの変更
Build Settingsの「Info.plist Preprocessor Prefix File」に、作成したInfo.plist用ヘッダファイルを指定。
※プロジェクトからの相対パス指定になるので注意。

更に「Preprocess Info.plist File」をYESに設定しておきます。

▼Info.plistの編集
Info.plistに「Application supports iTunes file sharing」を追加します。
追加後、Info.plistの表示をSourceCodeにしてキーの値を以下のように変更しましょう。
※「Application supports iTunes file sharing」のキーは「UIFileSharingEnabled」になります

<key>UIFileSharingEnabled</key>
<false/>

<key>UIFileSharingEnabled</key>
<string>DEBUG_FILE_SHARING_ENABLED</string>

booleanってどうやって指定するのかと思ったら、普通にで指定しても問題ないみたい。

▼動作の確認
実機で動作させてみて、PC側のiTunesを確認してみると、ファイル共有の箇所に自分のアプリが表示されている事が分かると思います。

これでマクロを使ってInfo.plistの値を指定できた事を確認できたので、だいたいこの時点で目的のほとんどは達成。
あとはビルド毎に値が切り替えられるようになれば完璧です。

プリプロセッサマクロでの切り替え (できなかった)
ところで、(メジャーな手法だと思うけど)私はNSLogによるデバッグログ出力有無を、Build Settings の「Preprocessor Macros」と#ifdef/#else/#endifの組み合わせで切り替えています。
そこで、info.plistの値もプリプロセッサマクロに合わせて切り替えできれば一番シンプルで分かりやすいかな、と安直に考えて調べてみました。

が、結論から言うと、出来ませんでした。。。

InfoDebugPreprocessor.hのdefineを #ifdef/#else/#endif で切り替わるようにしても必ず#elseの値が設定されるようで思うように動いてくれません。
Preprocessor Macros より Info.plist Preprocessor Prefix File の方が先にロードされてるように思えます。

ちなみにその際のInfoDebugPreprocessor.hのコードがコレ。

#ifdef DEBUG
  #define DEBUG_FILE_SHARING_ENABLED true
#else
  #define DEBUG_FILE_SHARING_ENABLED false
#endif

ぐぬぬ…。
※方法があればコメントくださると助かります。。。

▼Build Configuration毎に読み込むヘッダを切り替える
Build Settingsの「Info.plist Preprocessor Prefix File」の項目ですが、他項目と同じくConfiguration毎に分かれているます。
というわけで、プリプロセッサマクロでの切り替えは諦めて、DebugとReleaseで読み込むInfo.plist用のヘッダファイルを分けることにしました。

新しくReleaseビルド用のInfo.plist用ヘッダファイルを作成。
ここではInfoReleasePreprocessor.hとします。

InfoReleasePreprocessor.hにInfoDebugPreprocessor.hで宣言した同名のdefineをfalseで宣言しておきます。

#define DEBUG_FILE_SHARING_ENABLED false

あとはBuild Settingsの「Info.plist Preprocessor Prefix File」のReleaseに「InfoReleasePreprocessor.h」を指定すれば良いです。
Debugの方は「InfoDebugPreprocessor.h」のままね。

とりあえず、Build ConfigurationがDebugの状態で実行してみると、さっきと同様にiTunesのファイル共有にアプリが表示されていることが確認できました。

次はEdit SchemeからRunのBuild ConfigurationをReleaseに変更して実行してみると…
iTunesのファイル共有からアプリが消えました。

ドヤァ。

参考にしたページ。
▼stack overflow - Using preprocessor definitions in iOS App info.plist
http://stackoverflow.com/questions/14206621/using-preprocessor-definitions-in-ios-app-info-plist

半角カナを全角カナに変換する。

かんばんわ。

NSMutableStringとCFMutableStringRefは相互に型変換できるので、CFStringTransformを使えば半角カタカナを全角カタカナに変換できます。

 // 半角カナを全角カナに変換 
 NSMutableString* string =[[NSMutableString alloc] initWithFormat:@"ヴァーパピガギグ"];
 CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformFullwidthHalfwidth, true);
 [string release];

transformパラメータを変更することで様々な変換も可能です。カタカナをひらがなにすることも可能。すごいすごい。
上のコードではreverseパラメータをtrueにして逆変換していますが、falseにすると全角カナが半角カナになります。
また、 kCFStringTransformFullwidthHalfwidth はカタカナに限らず英字記号にも対応しています。

 // 全角記号を半角記号に変換 
 NSMutableString* string = [[NSMutableString alloc] initWithFormat:@"!”#$%&’()"];
 CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformFullwidthHalfwidth, false);
 [string release];

UIImagePickerControllerでカメラロール表示したらログにエラーが吐かれる

UIImagePickerController を表示する際に以下のエラーが吐かれる場合がある。

 <Error>: More than maximum 5 filtered album lists trying to register. This will fail.

よく分からないので調べてたら stackoverflowに同じトピックがあった。

回答には
「UIImagePickerControllerSourceTypeを設定する際には +[UIImagePickerController isSourceTypeAvailable:] を使ってsouceTypeが使用可能か確認すること」
みたいな形で書かれている。
それを実装したのが以下のコード。

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    } else {
        // アラート出したりすればええんちゃう? 
    }

UIImagePickerControllerのクラスリファレンス、isSourceTypeAvailable:の項目にもしっかり書かれていたりする。

ただ、確かにエラーを吐かなくなったが、、、エラー吐いてた時のコードに戻したら今度はエラー吐かなくなってしまった。
何か釈然としない。
iOSのDeveloperForumを見てても何で発生しているのかイマイチわからないんですよね。
xcodeのバグ?」みたいな流れになってるし。

今は諸事情からxcode4.2を使ってるのでxcode4.3.2では確認できてないけど、解消されてたりするんだろか。

plistの改行文字

かんばんわ。

小ネタですが、ずいぶん前にハマってしまったので記載。

plistに改行文字(\n)を含む文字列を設定してたいのですが、
いざ読み出して表示してみると「\n」がそのまま表示されてしまいました。

設定した文字列。

コードはこんな感じ。

    // info-plistのInfoStringに設定されているテキストを取得 
    NSString* str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"InfoString"];
    label.text = str;

▼実行結果
改行されずに表示されてしまう。

NSStringをstringWithFormat:で初期化すればちゃんと改行されて表示されるので、plistからの読み込みで変になっているようです。
えぇー・・・。

続きを読む

superviewの範囲外に配置されたviewにタッチイベントを送信する おまけ

かんばんわ。

前回の記事の最後で問題にぶつかりました。

なんか素早くドラッグしたらパネルビューが付いて来れずに置いてけぼりになっちゃってる〜〜〜!!!

えー・・・なんでよ・・・。

犯人はコイツだ!

    // 範囲外だったら無視する 
    if ((CGRectGetWidth(panel.frame)  >= touchPoint.x) && (touchPoint.x > 0) &&
        (CGRectGetHeight(panel.frame) >= touchPoint.y) && (touchPoint.y > 0) ) {

タッチ座標がパネルビューからはみ出てmoveを拾っていないだけでした。
コメントにも範囲外タッチイベントだったら無視するよ〜って書いてたのに…。

さらに上記とは別に、パネルビューの範囲外からドラッグしながらパネルビューに触れるとパネルが動いてしまう、という問題を発見してしまいました。
だめだめやん。。。

でも「superviewの範囲外に配置されたviewに対してタッチイベントを送信する」という本題は前回の記事で実装できているので、今回はそのオマケみたいな感じとなります。

続きを読む

superviewの範囲外に配置されたviewにタッチイベントを送信する

かんばんわ。

表題の件について、色々調べていたので現時点の状況を備忘としてまとめます。
同じような問題で困ってる方が居れば是非参考にしてください。

次のようなプロジェクトを作りました。

  • UIViewに250x300の背景ビューをaddSubviewする
  • 背景ビューに50x50のパネルビューをaddSubviewする
  • パネルビューをドラッグするとパネルビューが動く

簡単に言うと、画面上のパネルをドラッグすると動きます、というだけのプロジェクトです。
こんなかんじ。

続きを読む