ホームページ>開発ツール>Xcode and iOS SDK コラム
目次
Xcode and iOS SDK コラム
- UIView上のタッチスクロールが遅い(解決済)(2013/06/20)
- cssのみでiPhone風ボタンを作る(2013/06/04)
- UIScrollView上でUIButtonをハイライト表示する(2013/05/14)
- Xcode 4でビルドしたアプリを初代iPod touchで動かす(2)(2013/03/16)
- Xcode 4でビルドしたアプリを初代iPod touchで動かす(2012/04/05)
UIView上のタッチスクロールが遅い(解決済)
UIViewに画像を表示し、タッチによってスクロールさせようとすると、動作が劇的に遅くなる場合があったので、記しておきます。
(注:本件はシミュレータでは発生しません。実機(iPod touch 5thGで確認)でのみ発生します。)
遅くなったのは、以下のケースです。(実際にはもう少し複雑な処理をしていますが、説明のため、簡略化しています。)
この状態でスクロールしようとすると、カクカクした動きになる上、タッチを離すと、あらぬ位置でストップします。
- プロジェクトは、Single View Application
- 表示方向はポートレート(今回は、320x568)
- ViewContorollerとViewを新規に作成。ViewContorollerのビューにViewをaddSubview。ViewContorollerはappDelegateのウィンドウにaddSubview
- 568x320のイメージを作成して画像をコピー(コンテキストを経由)し、その後、90度回転してからUIImageの配列に登録
- タッチスクロールは、touchesBegan/touchesMoved/touchesEnded/touchesCancelledをオーバーライドして実装
- 起動したら、画像を配列から選んで表示
スクロールの度に再描画が発生する訳ですが、全く間に合っていない感じです。
結局、320x568のイメージを作成し、画像をコピーするときにコンテキストを回転するようにしたら解消しました。
シミュレータでは発生しないことから、ハードウェア依存だということは想像つきますが、因果関係については今ひとつよく分かりません。
回転して登録したものが遅くなるということは、UIImageってビットマップで持っている訳ではなく、回転とかは表示時にリアルタイムに行っているってこと?
cssのみでiPhone風ボタンを作る
iOS向けに、webkitを使って、cssのみでテーブルビュー風のUIを作れないかと思って調べてみたのですが、詳細表示ボタンが見つからなかったので、作ってみました。
(若干いびつでグラデも微妙ですが、必要なら調整して下さい。)
htmlのサンプルは以下の通りです。
cssは以下の通りです。<div class="detailDisclosureButton"></div>
注1)-moz-はFirefoxに必要なもので、iPhoneでのみ利用する場合は不要。.detailDisclosureButton { width:22px; height:22px; border:2px solid #FFFFFF; border-radius:13px; box-shadow:1px 1px 2px rgba(0, 0, 0, 0.6); background:-webkit-gradient(linear, center top, center bottom, from(#2385BA), color-stop(0.49, #2385BA), color-stop(0.5, #236ed8), to(#236ed8)); background:-moz-linear-gradient(top, #2385BA, #2385BA 49%, #236ed8 50%, #236ed8); /*float:right; margin:-3px 5px 5px 15px;*/ } .detailDisclosureButton::before { position:relative; content:""; display:block; background:#FFFFFF; width:3; height:10; top:4; left:11; -webkit-transform:rotate(-45deg); -moz-transform:rotate(-45deg); } .detailDisclosureButton::after { position:relative; content:""; display:block; background:#FFFFFF; width:3; height:10; top:-1; left:11; -webkit-transform:rotate(45deg); -moz-transform:rotate(45deg); }
注2)コメント化してあるパラメータは、セル内に配置する場合に必要なもので、marginの値は現物合わせで調整します。
UIScrollView上でUIButtonをハイライト表示する
UIScrollView上にUIButtonを置くと、ボタンを押してもハイライトせずに実行されてしまいます。
理由は、UIScrollViewが、画面への接触が「タップ」なのか「スワイプ」なのかを判定するために、若干の待ち時間を設けているため、ボタンの方が先に反応して実行されてしまう、ということのようです。(なので、暫く押し続けているとハイライトされます。)
どうにかならないものかと検索してみたのですが、自分の期待するような動作をするものは見つかりませんでした。
ちなみに、それらはtouchesShouldCancelInContentViewをオーバーライドする、scrollView.delaysContentTouchesをNOにする、といった、UIScrollView側を操作するものでした。
が、ふと「UIScrollViewの判定を早めるのではなく、UIButtonの実行を遅くすればいいのでは?」と思い、再度検索してみたら、performSelectorが見つかりました。
結局、以下の様にすることで、ハイライトされるようになりました。
ディレイ値(上記例では0.12秒)は現物合わせで調整すればいいと思います。UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; // ボタン生成 … [btn addTarget:self action:@selector(buttonDidPush1:) forControlEvents:UIControlEventTouchUpInside]; // ボタンが押された時の飛び先を指定 … - (void)buttonDidPush1:(UIButton *)btn { // スクロールビュー上でボタンのハイライトを確実に行うため、0.12秒のディレイを設ける [self performSelector:@selector(buttonDidPush2:) withObject:btn afterDelay:0.12]; // ディレイ満了後の飛び先を指定 } - (void)buttonDidPush2:(UIButton *)btn { // ボタンを押された時の処理を記述 }
あと、副作用?として、ボタン上でスワイプ(フリック)しても、(ディレイの期間内であれば?)スクロールするようになりました。
Xcode 4でビルドしたアプリを初代iPod touchで動かす(2)
先日、しばらくぶりに初代iPod touchを動かそうとしたのですが、またしても動かなくなっていました。
結論から書くと、以下の通り対処する事で、動くようになりました。
- Xcodeのバージョンを「4.4.1」にダウングレードする
- libSystem.B.dylibを「Optional」にする
注)前提となる検証環境は、前回と同じ。(ただし、メインは最新にしておきたいので、サブ(OSX 10.7 + Xcode 4.6)で実施している。)当初は初代iPod touchが切り捨てられていたことを知らずに、最新のXcode(4.6)で動かそうとしたのですが、オーガナイザで未対応(赤マーク)と表示されてしまいました。
調べてみたら、4.5から対応しなくなったとのこと。
仕方がないので、(4.5の一つ前の)4.4.1から試して、ダメなら遡ることにしました。
4系のアンインストールはゴミ箱に入れるだけなので、まずは4.6をゴミ箱に捨て、iOS Dev Centerから4.4.1をダウンロードしてインストール(アプリ単体のみの配布なので、アプリケーションフォルダにドラッグするだけ)。
オーガナイザで見たら、しっかり対応(緑マーク)していましたので、遡らずには済みました。
とはいえ、実機で実行すると、アプリが起動しかかったところでエラーが出て止まってしまいます。
エラーメッセージでググってみたところ、こちらに対応策が示されていました。(ハマケン100%開発: libSystem.B.dylibってなんだろう)
libSystem.B.dylibは、元々のリストにはないので、わざわざ追加した後にOptionalに設定し直すのがなんとも。(RequiredでないものはデフォでOptionalに、とかできないのだろうか…)これらの対処により、正常に動作するようになりました。
参考)本件と関係あるかは不明ですが、Safari 5.1.7が動かなくなっていました。再インストールしようとしたのですが、10.7用のSafariは単体では用意されておらず、ソフトウェアアップデートは何度実行しても(Safariが最新でないのにも関わらず)「お使いのソフトウェアは最新のものです」となってしまいました。半ば諦めていたのですが、Security Update 2013-001のタイミングで6.0.3がリストに現れ、そのままインストール。起動後、正常動作を確認しました。
Xcode 4でビルドしたアプリを初代iPod touchで動かす
Xcode 4でビルドしたアプリを、初代iPod touch(iOS 3.1.3)で動かそうとしたのですが、一筋縄ではいきませんでした。
結論から書くと、以下の通り対処する事で、動くようになりました。
- Deployment Targetを「3.1」にする
- Architecturesに「armv6」を追加する
- Debuggerを「LLDB」から「GDB」に変更する
注)前提となる検証環境は、以下の通り。1.と2.については、例えばこちらにまとめられています。(EZ-NET: Xcode 4.2 で iOS 4 用のアプリをビルドする : Objective-C プログラミング)
・検証用アプリは、以前、Xcode 3 + iOS 3.1ベースで作成し、初代iPod touchで正常動作を確認済のもの。
・同アプリ(のプロジェクト)をXcode 4で開き、標準の手続きでコンバートしたものを、シミュレータで動作確認。
・同アプリを初代iPad(iOS 5.1)で実行し、動作を確認。
なお、本検証の過程で、旧iOS用の追加SDKのインストールを促されたので、実行しています。
これらの対処により、アプリが実機に転送され、起動するところまではいきました。
ですが、起動はするものの、メインウィンドウが表示されず、ハングアップ状態になります。
Xcodeでの実行を一度終了し、実機単体で起動すると、ちゃんと動作しますので、どうも、アプリとXcodeの間で通信が出来ていないような感じです。
ググってみたのですが、(探し方が悪かったのか)有用な情報が見つからず、仕方なく、アプリ-Xcode間通信に関係のありそうなところを、片っ端から弄ってみたところ、DebuggerをLLDBからGDBに変更したところで、正常に動作するようになりました。
スキーム名をクリックするとメニューが表示されるので、Edit Scheme...を選択すると、右のダイアログが表示されます。 注1)TestタブにもDebuggerを選択する項目があるのですが、こちらは起動の可否には関係ないようです。(合わせておいた方がいい?)いずれにしても、デバッガは真面目に使っていないので、設定の変更がどう影響するかは定かではありません。
注2)何かのタイミングで「デバッガをLLDBにするか?」というダイアログが表示される事がありますが、選択しないようにします。
なので、これが正しい対処法なのかはよく分かりませんが、とりあえず実行は可能という事で、メモしておきます。
[Home] [MacSoft] [Donation] [History]