頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


Swiftでセルをタップすると一つ前にタップしたセルが選択される

Swiftにも慣れないとだめだろうなってことでちびちびとやってるんだけど、今まで簡単にできてたことが案外どうすんのよ?なんてことが多々あるんだ。

そんな時にはまったのがテーブル作成。UITableViewね。Objective-Cでなら今までに何度でも作ってきたテーブル。
それがSwiftだとどういうわけか
最初にセルをタップしても反応しない→次にタップすると一つ前にタップしたセルがタップされたことになる
というObjective-Cでは経験したことのない奇怪な状況に。
なんせ慣れないSwift、どこがおかしいのか検討つかないんだ。
"タップされた”というのはprintlnでチェックしてるんだけど、これが正しく動いてないのか?
セルの作り方がおかしいのか?
view controllerの初期化の問題か?
などとあちこち調べること数日、、、

ようやく不具合の理由がわかったんだ。
セルがタップされた場合にコールされるdelegateメソッドはご存知didSelectRowAtIndexPathだけど、Swiftだと何か使い方が違うのかと調べていたら見つけたページがこれ。

JamesonQuave.com • View topic - Part 4 - didDeselectRowAtIndexPath

一つ前にタップしたセルがタップされてるという俺と全く同じ症状じゃないか!
ようやく気付いた原因は、、、
tableView:didDeselectRowAtIndexPath:
↑メソッド名を間違えていた〜 orz

tableView:didSelectRowAtIndexPath:
↑こっちだろ!


↑少し前にこんなツイートもしてるという、、、案外気が付かないもんだね。


ROVIOのRETRYの課金方法に感心した

Angry BirdsのROVIOのRETRYってゲームがApp Storeのベスト新着ゲームに表示されていたので試してみたんだけど、これがなかなか面白くて。

Flappy Bird的なワンタップで自分の飛行機を操縦するゲームなんだけど、Flappy Birdと同様かなり難しく、何度も再挑戦(RETRY)するはめになる。

RETRYのスクショ

↑ホントすぐにぶつかっちゃう。

ただ飛行機が着陸できるところがあるので、着陸時にコインを使って飛行場をアンロックしておけば、失敗しても"再挑戦”はその飛行場からできる。
そのコインに課金するのよ、このアプリは!うまいねえ。
ホントすぐにぶつかってやり直しになるので、当然まめにアンロックしたいわけ。経路中にコインを取れることもあるんだけど、たいてい不足するんだよね。
10数秒くらいかの広告動画を見ればコインの代わりになる場合もあるんだけど、どういうわけか広告動画は無効なステージなんかもあって、やっぱりコインを買いたくなるようにできてる(買ったことはないけど)。


GLKMatrix4からsimd::float4x4への変換

まあこんなの使う人、そうそういないと思うんだけど、、、MetalやるのにSwiftではなくObjective-C++でGLKit系のメソッドなど(特にクォータニオン関連)を使いたかったのよ。
model view matrix や projection matrix を設定するあたりで欲しくなったんだわ。
-(simd::float4x4)convertToFloat4x4FromGLKMatrix:(GLKMatrix4)matrix
{
    return float4x4(
                    simd::float4 {matrix.m00,matrix.m01,matrix.m02,matrix.m03 },
                    simd::float4{ matrix.m10,matrix.m11,matrix.m12,matrix.m13 },
                    simd::float4{ matrix.m20,matrix.m21,matrix.m22,matrix.m23 },
                    simd::float4{ matrix.m30,matrix.m31,matrix.m32,matrix.m33 }
                    );
}
せっかく新しいの出たのだからとSceneKitのSCNMatrix4とかSCNVector3とか使おうかと思ったんだけど、クォータニオンまわりのメソッドがイマイチ(クォータニオン→行列にできないとかslerpできないとか)だったので挫折。
しばらくはどの言語やフレームワークを使うか悩みそう。


Blenderで表示されるクォータニオンをOpenGL ESで使う

Blenderの -Z Forward , Y Up の設定
↑Blenderで3Dのモデルを作成してそれをiOSアプリのOpenGL ESで使う場合に座標系が微妙に違うけどBlenderの出力時の設定でうまくいってる、というのをここで書いたんだけどさ。
こういうのがあるってのを頭の片隅に置いといて、、、

物体の姿勢をオイラー角じゃなくてクォータニオンで表す方がなにかと具合がいいので、OpenGL ES側ではクォータニオンだけ使うようにしてる。
この時、例えば物体の初期の姿勢を設定する時にクォータニオンで設定しておく、というのをしようとしたのよ。

Blenderで姿勢(角度)がどのように表されてるかを確認すると

Blenderでの姿勢(オイラー角)

↑多分デフォルトだとXYZ Eulerになってるのかな。オイラー角になってるはず。
この部分選択できるようになってて、Quaternion (WXYZ)ってのに変えると

Blenderでの姿勢(クォータニオン)

↑クォータニオンの4つの数字が出てくる。ありがたいじゃない!
この数字、OpenGL ESでそのまま使えるのかな?と思って試してみたのよ。

例えばBlenderでのy軸まわりに回転させてみる。

Blenderで回転

↑真正面から見るとこんなのね。

この時のクォータニオンは図にあるように ( 0.0 , 0.259 , 0.0 ; 0.966 ) ね。

OpenGL ES (iOS)で物体の姿勢としてこのクォータニオンを設定すると

OpenGL ES(iOS)で回転

↑あら?期待してたのと違う?
確かにy軸まわりに回転してることはしてるんだけどね。
そうかあ、Blenderで表示されるクォータニオンのままだとこうなっちゃうから何か補正が必要なんだな。

ということで、

90度回転でうつ伏せ

↑オブジェクトを90度回転。これでBlenderと同じようにy軸がロボットのおなかに垂直になる。

60度回転
↑ちょっとわかりにくいので60度回転させた図がこれ。うつ伏せになってる。

クォータニオン適応時

↑うつ伏せの状態でクォータニオン( 0.0 , 0.259 , 0.0 ; 0.966 )による回転を適用するとこうなる。

90度戻した場合

↑元に戻して(-90度回転)完了。

こういう補正をすればとりあえず、Blenderで表示されるクォータニオンを使えることはわかった。
まあ一手間増えるけど、かといってBlenderでy軸を上にしてモデルを作成したり動かしたりするのがなんともやりづらかったのでこの方法でいくわ。


iPhoneをリセットしてもiOSのバージョンは変わらなかった

iOS 8.0のiPhone 5sをリセットしていわゆる工場出荷時の状態にしたんだ。実際は設定/一般/リセット/すべてのコンテンツと設定を消去ってやつで。
リセット後に別なSIMで新しいiPhoneとしてアクティベーションした後に確認したらOSのバージョンは変わらず8.0のままなんだな。もちろん"工場出荷時"は8.0ではないし、最新は8.0.2だし。
"工場出荷時"ってよく聞くからどうなるのかな?と思っていたんだけど、そういうものなのね。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.