.-- --

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
スポンサー広告 comment(-) trackback(-)
.26 2010

キーボードの非表示

Tasakiです。

毎週恒例のSDKアップデートがないなと思ったら…先日審査が開始されたんでしたね。
今更、変更になっても迷惑な話ですけども。
そもそも、日本での発売日も不明な中で、あまりリリースされるって実感は湧いていないところです。

さて、今日のテーマですが、簡単にキーボードを非表示にする方法をご紹介します。
キーボードを非表示にする場合、公式ドキュメントによると、フォーカス中のテキストエリアに対し、
- ( BOOL ) resignFirstResponder
を呼ぶ方法が紹介されていますが、この方法は意外と厄介な問題を含んでいます。
それは、フォーカス中のビューを特定しなければならないということです。
また、先にisFirstResponderでファーストレスポンダであることを確かめておかないとエラーの原因になってしまいます。

これを解消できるのが、以下のメソッドです。
- ( BOOL ) endEditing:( BOOL ) force

例えば、ビューコントローラが、サブビューとして複数のテキストフィールドを管理していて、それらのうちのどれかにフォーカスが当たっている可能性がある場合は、次のコードで処理できます。
[ viewController.view endEditing: YES ];

使ってみて感じましたが、非常に便利です。
知らなかったという方はぜひお試しください。

それにしても、アップルはなぜこのAPIを勧めてくれなかったんでしょうか…


スポンサーサイト
.19 2010

beta5…いつまでやるんだ

Tasakiです。

最近SDKの更新が週1ペースになってるような気がするんですが、追い込みの時期なんでしょうかね。
beta4からの変更点もあるみたいですが、少なっ!と思わず突っ込みそうになりました。

世間的にもそうでしょうけども、こちらも追い込みに入ってきちゃいまして、あまり時間が割けないため、技術ネタの紹介はお休みにさせていただきます…
.12 2010

NSInvocationで動的結合を体感

Tasakiです。

今週、SDK3.2もbeta4がリリースされましたね。
実機の方も4月発売ということで、国内ではXperia vs iPadな状況になってきました。
これで3G版のキャリアがdocomoなら、まさにそういう構図になりそうですが…

今回のテーマは、Objective-Cの特徴でもある動的結合に関するものです。
Objective-CはCに動的結合の機能を付加したものと言っても過言ではないですし(ですよね?)、この機能は抑えておいた方がよいでしょう。

Objective-Cのメソッドは通常、[ obj call ]といった様に直接呼び出すのが。
この他に、以下のようにセレクタを渡して、間接的にメソッドを呼び出す方法もあります。
[ obj performSelector: @selector( call ) withObject: nil ];
2番目の引数には、先頭のパラメータを渡します。
上の例では、引数を取りませんので、nilにしておきます。

では、引数が2つある場合はというと、以下のようになります。
[ obj performSelector: @selector( call:withA:withB: ) withObject: arg1 withObject: arg2 ];

しかし後ろにパラメータが増えていくこの方法では、どう考えても対応に限界があります。
というわけで、3つ以上の引数を取る場合は、別の方法をし使用しなければなりません。
また、この方法では、引数がObjective-Cのオブジェクトである必要がありそうです。

そこで登場するのが、NSInvocationクラスです。
このクラスを使用するとより複雑なメソッドでも呼び出しが可能になります。

以下に処理の流れを示します。
1.メソッドシグネチャを取得
2.上記オブジェクトからインボケーションオブジェクトを作成
3.ターゲットオブジェクトを設定
4.ターゲットセレクタを設定
5.引数を設定
6.メソッドの呼び出し
7.返り値の取得

例として、NSStringの以下のメソッドを呼び出す場合は、
- ( NSString* ) stringByReplacingOccurrencesOfString:( NSString* ) target withString:( NSString* ) replacement options:( NSStringCompareOptions ) options range:( NSRange ) searchRange

次のようになります。
NSString* string = ...;
NSString* target = ...;
NSString* replace = ...;
NSStringCompareOptions options = ...;
NSRange range = ...;
NSString* retVal = nil;

SEL selector = @selector( stringByReplacingOccurrencesOfString:withString:options:range: );
// メソッドシグネチャを取得
NSMethodSignature* signature = [ string methodSignatureForSelector: selector ];
// インボケーションを作成
NSInvocation* invocation = [ NSInvocation invocationWithMethodSignature: signature ];
// オブジェクトを設定
[ invocation setTarget: string ];
// セレクタを設定
[ invocation setSelector: selector ];
// 引数を設定
[ invocation setArgument:( void * ) &target atIndex: 2 ];
[ invocation setArgument:( void * ) &replace atIndex: 3 ];
[ invocation setArgument:( void * ) &options atIndex: 4 ];
[ invocation setArgument:( void * ) &range atIndex: 5 ];
// メソッドの呼び出し
[ invocation invoke ];
// 返り値の取得
[ invocation getReturnValue:( void * ) &retVal ];

注意点としましては、
・引数や返り値の受け渡しには、変数のポインタを使用する
・引数設定の際のインデックスには、引数の順番 + 1 を使用する
等が挙げられます。

たった1つのメソッドを呼ぶだけでこのような労力が必要となってしまいますが、クラスやメソッドが未定義であっても、コンパイルエラーを回避することが可能になり、場合によっては必要となるテクニックであることは確かなので、覚えておいて損はないでしょう。

.05 2010

ライブラリの導入

Tasakiです。

AppStoreの審査基準変更で混乱が生じているようですね。このところ、こういったケースが増えてきているので、開発者としては不安が募ってくるばかりです。昨日までOKだったものが次の日にはNG扱いになっちゃうわけですからね。アプリが完成したタイミングで、これやられたらと考えると…ゾッとします。

まあ、ネガティブな感じで始まってしまいましたが、今回は外部ライブラリのインポートについて、手順を追いながら、注意点を挙げてみたいと思います。iPhone向けのオープンソースライブラリも増えてきてますし、利用する機会も多くなってきてますので。

1.ライブラリのバンドル
外部ライブラリ(.aファイル)をプロジェクトにインポートします。
通常のファイル追加操作も利用できますが、実機用とシミュレータ用でリンクするライブラリを動的に変更する場合は、以下のようにします。

a.リンカフラグの設定
図に示す、ターゲットのビルド構成情報の「他のリンカフラグ」に -l<ライブラリ名>の記述を追加します。
リンク
例えば、ライブラリファイルの名称が、libTest.aである場合には、-lTest と記述します。
通常は、-ObjCもしくは、-all_loadも記述しておきましょう。

b.ライブラリ検索パスの追加
同リスト内にある「ライブラリ検索パス」にライブラリファイルが格納されたパスを追加します。
検索パス
例えば、実機用のライブラリファイルが
<プロジェクトフォルダ>/Libraries/lib/iphoneos、
シミュレータ用が
<プロジェクトフォルダ>/Libraries/lib/iphonesimulator以下に配置されている場合は、
$(SRCROOT)/Libraries/lib/$(PLATFORM_NAME)とします。
こうすると、実機用とシミュレータ用で別々のライブラリであっても、ビルド構成をDeviceにすると、実機用のライブラリが、SImulatorにすると、シミュレータ用のライブラリが自動的にリンクされるようになります。とても便利です。

2.ヘッダファイルの追加
ライブラリ用のヘッダファイルをインポートします。
これも、通常のファイル追加操作を利用してもいいですし、以下のように、ターゲットのビルド構成情報の「ヘッダ検索パス」にヘッダファイルの格納されたパスを登録してもOKです。
検索パス
例えば、ヘッダファイルが、
<プロジェクトフォルダ>/Libraries/include以下に保存されている場合には、
$(SRCROOT)/Libraries/include/を追加します。
すると$(SRCROOT)が現在のプロジェクトフォルダのパスに置換されます。
内部でさらにフォルダが切られている場合は、再帰的にチェックしておけばOKです。

あとは、ビルドして確かめるのみです。
エラーが発生した場合の対策ですが、
・ヘッダファイルの配置漏れがないか確認する
・ライブラリ検索パス、ヘッダ検索パスが正しいか、よく確かめる
・リンカフラグを確かめる
これを徹底すれば、ライブラリのリンクに関する問題は、ほとんど解決できます。

ただ、自作ライブラリ等でライブラリ自体に欠損(ヘッダファイルの追加漏れ等)がある場合も考慮しなければなりません。
ライブラリのビルドに成功していても、アプリケーションプロジェクトにリンクしてみて初めて分かる問題なので、要注意です。

僕の経験上、ライブラリを利用する際に何度も体験するハメになる問題です。一度ハマると、ポインタの不正参照と同レベルくらいに厄介です。これが助けになれば幸いなんですが。

 HOME 

ブログ内検索

関連リンク

製品情報

最新記事

カテゴリ

プロフィール

neoxneo



NEXT-SYSTEM iOS Developers Blog


  • UTO:
    カナダ版iPhone4Sは、マナーモードでシャッター音がならない…


  • Ehara:
    ...


  • Hayate:
    ...


  • Tasaki:
    Developer登録完了...したのはいいけど


  • Ueda:
    ...



リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。