投稿

ラベル(iOSアプリ開発)が付いた投稿を表示しています

キーボードの出入りに合わせる自前アニメーション処理は不要

UITextViewなどがファーストレスポンダになったときにキーボードが出てきて、それと同時に画面上のUIパーツもキーボードで隠れないように上に移動させることがよくあります。 キーボードの動きとUIパーツの動きのタイミングを合わせると見た目がシンプルになります。このUIパーツのアニメーションを自分で書くのではなく、OSに任せることが出来ます。 やり方 keyboardWillShowNotificationを受けたときに走らせるメソッドで、動かすUIパーツのframeやcenterの情報を書きます。あとは自動でアニメーションを行ってくれます。 シミュレーションで確認してみると、これが出来るのはiOS10からのようです。 自動でやってくれるのはUIパーツのframeの設定だけでなく、UITextViewの大きさを変更したときにカーソルが表示領域に入るようにスクロールオフセットの値を調整するのもやってくれるようです。 キーボードが出てくるときと同様にキーボードがしまわれるときは keyboardWillHideNotification を使います。 いたれりつくせりですね。 https://stackoverflow.com/questions/39292796/why-is-a-uiview-whose-frame-i-change-after-receiving-a-uikeyboardwillshownotific https://stackoverflow.com/questions/35914577/uikeyboardwillshownotification-animation https://stackoverflow.com/questions/39292796/why-is-a-uiview-whose-frame-i-change-after-receiving-a-uikeyboardwillshownotific https://medium.com/@shenghuawu/observe-ios-keyboard-notifications-a49323813656

iOS8対策、アプリ内のhtmlファイルをWKWebViewで表示

アプリの中にhtmlファイルを持ち、それをWKWebViewで表示する方法です。iOS8向けです。iOS8のWKWebViewではhtmlファイルがロード可能なところにファイルがないと読み込めないので、その場所にコピーする手間が生じます。iOS9ではその必要はありません。ここで想定している規模は、ベースとなるhtmlの他に画像ファイルが何点かある場合です。向いているのは、文章と画像が中心のもので、ブラウザにレイアウトを任せたいものです。例えばアプリの使い方の説明などがあるでしょう。 関連するファイルのかたまりを管理するstruct これは、ひとつのページに関連するファイルをまとめて扱うためのstructです。この記事はひとつのページに画像が数点あるようなものを想定しています。 struct FileList { let baseHTML: String let includedFiles: [String] } baseHTMLは拡張子が.htmlのファイルです。 includedFilesはそこに含まれる画像ファイルなどの配列です。拡張子も含めます。 ViewController WKWebViewインスタンスを作成し、viewにWKWebViewインスタンスを貼り付けます。 上で定義したFileListのインスタンスを作り、load(fileList: , tempName: )を呼びます。 load(fileList: , tempName: )は後で説明します。 class ViewController: UIViewController { let webView = WKWebView() override func viewDidLoad() { super.viewDidLoad() webView.frame = self.view.frame self.view.addSubview(webView) let fileList = FileList( baseHTML: "test.html", includedFiles: ["Image.png...

アプリを iPad Pro 10.5 インチに対応させるには

イメージ
iPad Pro10.5インチが出ました。 既存のアプリを10.5インチ画面に対応させるわけですが、Xcode上でどこを設定すれば対応になるのか疑問です。ここで言う対応とは画面のサイズを取得したときに1112×834(10.5インチiPadのデータ)が得られる状態のことを言っています(コードは下記)。前回の12.9インチの時は苦労しました。 いろいろ触って見つけました。 今回はRequires full screenのようです。 なんでこんなに微妙なところにするのか Requires full screenをONにするとシミュレータで10.5を選択し起動しても9.7のサイズ(1024×768)が取得できます。 Requires full screenをOFFにするとシミュレータで10.5を選択し起動すると10.5のサイズ(1112×834)が取得できます。 override func viewDidLoad() { super.viewDidLoad() let deviceHeight = UIScreen.main.bounds.height let deviceWidth = UIScreen.main.bounds.width print(deviceHeight, deviceWidth) } 環境は、Xcode 8.3.3上でプロジェクトの作成とシミュレータ実行を行いました。 これ以外にある可能性もありますし、このやり方が常にうまくいくとは限らないと思いますが。

Swift2.2からSwift3.0への変換を行ってみて

イメージ
Xcode8のGMが出たので、Swiftを2.2から3.0へ変換しました。自動でコンバートするXcodeの機能を使いました。 変換箇所があらかじめ表示されるので、一通り見て気が付いたことを書いていこうと思います。 enumの要素の頭文字が小文字に統一 どっちが正解なのかなぁと思いながらプログラムを作成していた部分なのではっきり決めてくれて良かったです。 配列の初期化メソッド 配列の初期化によく使われる init(count: repeatedValue: )が init(repeating: count: ) になりました。順番が変わって、さらに現在分詞になりました。 NS抜け NSBundle が Bundle へ変更 NSIndexPath が IndexPath へ変更 NSURL が URL へ変更 Appleに従うのみ。 タイプメソッド扱いしていたものがタイププロパティ扱いに NSBundle.mainBundle() が Bundle.main へ変更 UIScreen.mainScreen() が UIScreen.main へ変更 UIDevice.currentDevice() が UIDevice.current へ変更 UIColor.whiteColor() が UIColor.white へ変更 //例 open class var white: UIColor { get } 従うのみ。 CoreGraphics衣替え CGRectMakeなどのC言語ベースのCG***関数がSwift3.0では廃止になっています。 (旧)CGRectMake(***) が (新)CGRect(***) へ変更、CGRect(***)の方はSwiftの構造体のinit命令呼び出しです。 (旧)CGPointMake(***) が (新)CGPoint(***) へ変更、CGPoint(***)の方はSwiftの構造体のinit命令呼び出しです。 (旧)CGRectContainsPoint(CGRect rect, CGPoint point) が (新)CGRectインスタンスに対するcontains(_:)メソッドへ変更 (旧)CGContextFillPath(CGContext...

iOS10対策

イメージ
Privacy - Media Library Usage Description この問題はシミュレータ(Xcode8.0)で発生したが、実機では発生しませんでした。 iPodライブラリの曲をアプリ内で使うとき、ユーザーに許可を取るようになりました。 この時の文面をinfo.plistに設定する必要があります。 Privacy - Media Library Usage Description(rawキーではNSAppleMusicUsageDescription)に何か文を追加します。 これを設定しておくと、アプリがライブラリにアクセスしようとしたところで、Don't allow / OKダイアログをOSが勝手に出してくれて、その中に先ほどの自分で追加した文が表示されます。 これを設定しないと、アプリが落ちます。 出す文章を各言語毎に変えたい時は、InfoPlist.stringsのローカライズをするとよいでしょう。 xibファイルのBuilds for この問題はシミュレータ(Xcode8.0)で発生したが、実機では発生しませんでした。 [UIDeviceRGBColor length]で実行時エラーが発生しました。これは自分で書いたプログラムではないので原因がわかりにくかったのですが、xibファイルのBuilds forが未設定でした。Xcode3の時に作成したプロジェクトで発生しました。xibファイルのBuilds forをDeployment Target (8.0)にしました。

Swift2 標準ガイドブック

説明は全体的にざっくりアバウトな感じなので荻原本などを併用すること。 イニシャライザの項目に間違いが多いので修正があるといいです。

詳解Swift改訂版買いました

詳解Swift改訂版を買いました。 Objective-C版も持っています。Objective-C版に比べて推敲が甘いかなと感じる部分が特に最後の方で多かったです。版を重ねて修正が加わるといいです。 以下、自分用のメモ。 構造体 イニシャライザ内でメソッドを呼ぶのは初期値設定が全部済んでから。 構造体の内部で別の構造体を定義出来る。 構造体の内部で、typeエイリアスを使って、別名を与えることが出来る。(メリット?) タイププロパティの値を変更するインスタンスメソッドにはmutatingは不要。 タイププロパティの初期化のための式は値が必要とされた時に初めて評価される。 didSet WillSetはinit()内での設定では呼ばれ無い。didSetで値を設定しても再帰的に呼ばれることはない。 オプショナル オプショナル==nilはnilかどうか オプショナル==非オプショナルは中身を比べることが出来る if letのほかにif varもある readLineは標準入力 ??の右はオプショナルでもいい。??は連鎖できる。 配列 配列を反対にするreverse()というメソッドがある。 String Characterの配列からStringインスタンスを作るinitメソッドがある UnicodeScalarにはvalueプロパティがあって値を取り出せる 辞書 新規はdict[a] = aaa 削除はdict[b] = nil updateは更新、ただしもとからない場合は作成しない。 Tuple let aTuple = (1, 2, 3) let (a, b, c) = aTuple //これが出来る let (aa, _, _) = aTuple //使わないときは_が使える 値が一つだけのTupleはその値だけと変わらない 要素が一つもないことを()で表現。Voidは()の別名 違うキーワードのTuple間の代入は無理。型が同じでも。一度キーワードなしにキャストすればOK キーワード付きのタプルの代入では順番が違っていてもキーワード毎に要素が代入される。キーワードがない部分は順番通りに代入される。 タプルにTypealiasでなまえをつけることができる。 Switch オプショナル付きのタプルを扱える switch a ...

従来のソフトのままでiPad Proの画面に対応する方法

イメージ
以下の記事はちょっとまだ公式のソースを確認できていないので自己責任でお願いします。 iPhoneが3.5インチサイズから4.0インチサイズに移行したときは4.0用の起動画面を用意することで4.0に対応していることを示すやり方でした。用意しなければ真ん中に3.5インチサイズの画面が出て、黒い帯で上下の空いた領域を埋める仕様でした。iPhone6や6sのときも対応/非対応の区別は起動画面を用意するかしないかでした。 今回iPad Proが新規解像度2732 x 2048で出てきましたが、対応/非対応のポイントはやはり起動画面のようです。 ただ今回はファイルを用意するのではなく、Launch Screen File(storyboard風のやつ)が設定してあることが「iPad Proに対応している(2732 x 2048も想定して描画処理を書いてある)」ことを示すようです。図のSourceのほうではなくてFileのほうです。iPad Pro対応しないとき(iPadのレギュラーサイズの画面を引き伸ばしたいとき)は「なにも設定しない」にしてください。こうすることで内部でiPadレギュラーサイズとして描画したものをiPad Proの画面の大きさに引き延ばすような処理になります。 ちょっとまだ公式のソースを確認できていないので自己責任でお願いします。実機はまだ発売されていないので確認したのはシミュレータのみです。Xcodeは7.1です。 未来ぽい感じがして好きだったんですが一旦OFFにしておきますかね。

iOS9対応でやったこと

[NSLocale preferredLanguages] [NSLocale preferredLanguages]で返ってくる言語設定が iOS8まで ja iOS9から ja-US のようになったので対応。 isEqualToString:@"ja" から hasPrefix:@"ja" へ変更すればOKと思いましたが ジャマイカ... が脳裏をよぎり isEqualToString:@"ja"とhasPrefix:@"ja-"のORにしておきました。 NSManagedObjectContext [[NSManagedObjectContext alloc] init]が9.0でdeprecatedになったので [[NSManagedObjectContext alloc] initWithConcurrencyType:] に変更しようと思ったがConcurrencyTypeの設定が難しすぎて一旦保留。 Requires full screen iPadアプリで「全方向対応でない場合はRequires full screenをONにするように」というワーニングが出たのでONにする(そのアプリは縦のみ対応)。 このパラメータはSlide OverやSplit Viewで画面の一部の表示をされたくない時にもONにするものらしい。 (追記 : 以下のバグはXcode7.1.1では修正されていました) ちなみにiOS9.0 Xcode7.0の段階でSlide OverやSplit Viewを有効にするとなぞのバグ(?)があって、 フルスクリーン状態で(Slide OverやSplit View状態ではない)デバイスを回転させて、UIDeviceOrientationDidChangeNotificationを受けた時に self.view.bounds.size.width self.view.bounds.size.height が変更前の状態で取得されてしまって使えなくなるという現象があった。その値を元に全体の要素を配置しているので、縦にすると横の配置になり、横にすると縦の配置になるという現象。 [[UIApplicati...

詳細!Swift iPhoneアプリ開発 入門ノート

表紙はiOSプログラミング本にはめずらしいオレンジ色。(初版) 6章以降は、アプリを作ったことがあるとちょうどいい内容です。サンプルはなかなかコアなところを選んである。 今までiOSアプリを作ったことがない人が、これで一からやろうとするときついと思う。今までにいくつかアプリを作った人でないと理解できないような表現がけっこうある。

UIFontのfontName一覧 iOS8版

参考記事 Over&Out その後 UIFontのfontName一覧 これのiOS8版を行います。 ""が付いているものと付いていないものがありますが、どちらも指定できます。 使用例 [UIFont fontWithName:@"Courier" size:512]; family:Marion ( "Marion-Italic", "Marion-Bold", "Marion-Regular" ) family:Copperplate ( "Copperplate-Light", Copperplate, "Copperplate-Bold" ) family:Heiti SC ( "STHeitiSC-Medium", "STHeitiSC-Light" ) family:Iowan Old Style ( "IowanOldStyle-Italic", "IowanOldStyle-Roman", "IowanOldStyle-BoldItalic", "IowanOldStyle-Bold" ) family:Courier New ( "CourierNewPS-BoldMT", "CourierNewPS-ItalicMT", CourierNewPSMT, "CourierNewPS-BoldItalicMT" ) family:Apple SD Gothic Neo ( "AppleSDGothicNeo-Bold", "AppleSDGothicNeo-Thin", "AppleSDGothicNeo-UltraLight", "AppleSDGothicNeo-Regular...

bridge系のキャスト

よく忘れてしまうので… 何がカウンタ方式か ARC obj-cでも非ARC obj-cでもCF系(CoreFoundation系)でも全部カウンタ方式。プログラマが管理文を書くか書かない(コンパイラが書く?)かの違いはある。 カウンタはどこで持つか 2つの変数が同じインスタンスを参照している時カウンタはいくつか? 1つ。 __bridge系って何? id系とCF系のキャストの箇所でコンパイラがretainとreleaseをどう書くかを指定するもの。 __bridge __bridge_retained __bridge_transfer の3つ。 何をどう使ってもretainとreleaseがきちんと数を合わせて実行されてれば間違いではないと思いますが、3種類あるのは、人が見てわかりやすいとか、下で書くような管理責任をどうしたいのかを表すのには便利かと思います。 オーナーシップについて オーナーシップという言葉で説明してあるものがかなりあります。もしよくわからない場合は、一旦retain releaseの追加という観点で理解してから、再度オーナーシップについて考えるのがおすすめです。 それぞれのパターンでキャストして代入するとこうなります。 __bridgeによるCF系からid系 id系 = (__bridge id系)CF系 id系がARC管理下に入ることによりカウンタ+1。ただし__weakであれば増加処理はなし。 キャスト後もCF系で管理したいときにおすすめ。id系が消えたあともCF系を使いたい時など。 __bridgeによるid系からCF系 CF系 = (__bridge CF系)id系 カウンタ変わらず 引き続きid系による(自動)管理をしたいときにおすすめ。キャスト後のCF系は管理しないことが前程だが一応管理命令は実行出来る。 __bridge_retainedによるid系からCF系 CF系 = (__bridge_retained CF系)id系 CF系がretainされるので+1 キャスト後のCF系で管理したいときにおすすめ。 id系は引き続き管理されている。 __bridge_transferによるCF系からid系 id系 = (__bridge_transfe...

Unmanaged Objects

Swiftはいろいろと新しい設計がしてあって便利なんだけど、既存のものとの互換性という点で困ることがよくある。今回の内容もそのひとつ。メソッドの実行結果としてCore Foundationを受け取ってしまったとき。 返されたCore Foundationオブジェクトはおそらくメモリ管理がされていないUnmanaged<T>という型(?)となっている。Swiftはこのままでは使うことが出来ず、プログラマがこれをretainタイプ(CF_RETURNS_RETAINED)か非retainタイプ(CF_RETURNS_NOT_RETAINED)に決定してやる必要がある。これをするにはそのオブジェクトに対して takeUnretainedValue() か takeRetainedValue() を実行してやる。 説明に載っていた使用例は以下の通り func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>! let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue() ポイントはretainタイプか非retainタイプかをどう判断すればいいのかということ。自分のプログラム内での使われ方から判断し、retainが必要ならretainすればいいのかなと思うのだが、今後の課題。

iOS8のTabViewControllerでのViewがLoadされるタイミング

iOS8ではViewがLoadのされるタイミングが少し変更されているようです。 以下の記事ではSegue実行時の流れを調べました。 http://samekard.blogspot.jp/2012/03/storyboard.html この記事では次のように書きました。 1 performSegueWithIdentifier開始 2 新しいViewControllerのインスタンス化(initなど) 3 prepareForSegue開始 4 prepareForSegue終了 5 UIKitのインスタンス化、画面回転メソッドの呼び出し、viewDidLoadなど 6 performSegueWithIdentifier終了 iOS8でも移行先のViewControllerがシンプルなものであればこの通りなのですが、TabBarControllerの初めに表示されるViewControllerの場合はこのようになります。 4 prepareForSegue終了 5 performSegueWithIdentifier終了 6 UIKitのインスタンス化、画面回転メソッドの呼び出し、viewDidLoadなど (2番目移行に表示されるViewControllerは表示の直前でViewをLoadします) TabViewControllerに乗っている各ViewControllerのViewはperformSegueWithIdentifierより後でインスタンス化するようです。ちなみにViewController自体は2の時点でインスタンス化されます。

Reachability 3.5

iOSアプリ内でネットワークの情報を取得するReachability 3.5を使用した際の感想。 Reachabilityの情報はWeb上にいろいろありますが古いバージョンの情報になっている場合もある。今回3.5を使用してみました。 Reachability.h Reachability.m をプロジェクトに追加 #import "Reachability.h" のimport文を追加 - (BOOL)checkNetwork{ BOOL returnVal = NO; Reachability *reachablity = [Reachability reachabilityForInternetConnection]; NetworkStatus status = [reachablity currentReachabilityStatus]; switch (status) { case NotReachable: break; case ReachableViaWWAN: returnVal = YES; break; case ReachableViaWiFi: returnVal = YES; break; default: break; } return returnVal; } のメソッドを追加 バージョン3.5とiOS7の組み合わせではフレームワークの追加は必要無かった模様

UITabBarController

UITabBarControllerを使用する上で気がついたことなど 構成 2タブ仕様にするときは UITabBarController(親) UIViewController(子) UIViewController(子) の3つのController構造になる。 子UIViewControllerを追加するとき Storyboardで普通にUIViewControllerを追加し、 親UITabBarControllerからSegueのように接続線を引くとUITabBarControllerに対応した項目が出てくるのでそれを選択する。 画面回転の制御 親UITabBarControllerサブクラス内に記述する模様

Xcode5のLocalize

昔はローカライズしたときには English(デバイスの設定が日本語以外の時はこちらが選ばれる) Japanese の2つを作っていたけど、今はBaseというものも作れる。 なので Base(中身は英語、デバイスの設定が日本語以外の時はこちらが選ばれる) Japanese の2つでいいんじゃないだろうか。 これは仮定なのでいろいろ調べて行きたい。

iOSアプリ開発に関する細かいこと Objective-C編

個別に記事にまとめるほどでもないiOSアプリ開発に関する細かいこと 画像の端をにじませる Renders with edge antialiasing 画像の端をにじませる info.plistで設定する Localizable.strings NSLocalizedString(@"distanceLabel", nil); Localizable.strings "distanceLabel" = "距離"; なぜDeployment Targetの設定箇所は2つあるのか Deployment Target(アプリ動作可の最低ライン)はPROJECTとTARGETにそれぞれあり、2つあることになる。TARGETのほうは初めは薄い色になってる。PROJECTで設定するとそれに伴いTARGETの値も変わる。別にするメリットも殆ど無いと思うので、設定はPROJECTだけにすればよいと思われる。一度TARGETを何かに設定してしまうと「連携モード」に戻す手段がわからないので、「連携モード」を解除したくないなら触らないほうがいい。 Build SettingsのCode Signing IdentityとProvisioning Profile Code Signing Identity 証明書の選択。Provisioning fileではない。証明書を選べば対応するProvisioning fileも選ばれることになるので、Provisioning fileの選択と解説される場合もある。Automaticの欄にあるiOS DeveloperやiOS Distributionを選んでおけばその名前で始まるものが自動で選ばれる。 Provisioning Profile Automaticになっていれば自動で選ばれる(上で指定されている証明書とBundle Identifierを基に選ばれるのかと思われる)。 statusBarOrientation [[UIApplication sharedApplication] statusBarOrientation] viewDidLoadで正確な値が取得出来るかどうかは要調査。 複数引数メソッドの遅延処理 doubl...

iOS 7について

気になるのはC言語ベースのAudioSessionが非推奨になったこと。 AVAudioSessionを使え、とのこと。 以前、AVAudioSessionの一部分が非推奨になったために、アプリを作る際はAudioSessionのほうに統一した方がいいんじゃないかという内容を書きましたが、こんどはAVAudioSessionの方を推奨するようです。 他に気付いたもの AVSpeechSynthesizer AVSpeechUtterance しゃべらせることが出来る?

iOS 7 Design Resources

iOS7のいろいろな資料を読んでのメモ書き。 iOS7はこれまでのバージョンアップより資料が多い気がする。 iOS 7 UI Transition Guide 起動画面 以前からiPhone用の起動画面は画面全体を覆うものだったがiPad版のほうはステータスバーの領域をカットする1004x768のような中途半端なものだった。これがiOS7からはiPad iPhone共にステータスバーの領域をカットしないものになった。画面全体を覆う画像を用意すればいい。 アイコン iOS7で使用するアイコンの大きさは変更になった。 120 x 120 iPhone iPod touch 76 x 76と152 x 152 iPad 120 120の場合、枠のカーブはだいたい34から10へのベジエ曲線。 76 76の場合、枠のカーブはだいたい22から6へのベジエ曲線。 起動画面、アイコン共に、Xcodeでどのファイルをどれとして使用するかを関連付けるようになった。前までは名前の決まりがあったがなくなったかもしれない。 ステータスバーが非表示に出来なくなったようです。