Swiftで使える小ワザを集めてみた (アプリ開発, トラブルシューティング)







Safe Area のマージンを取得したい


iOS11から利用できる self.safeAreaInsets を使って取得できる。
次のようにViewにextensionを定義しておくと便利。
使う時は self.view.csSafeAreaInsets.top のようにできる。





画面の回転を検知したい


画面回転時のイベントをフックするには UIDevice.orientationDidChangeNotification をオブザーバー登録する必要がある。
向きが変わった時だけ処理をさせたい場合は、下のプログラムのように lastOrientation などで以前の状態を保持しておく工夫が必要である。





UIViewControllerのクラス名を取得したい


次のように UIViewController を拡張しておくことで、他のクラスで UIViewController が渡された時にクラス名で条件分岐できるようになる。






同じクラスタイプのViewを一括で操作したい


例えば、UISegmentedControlがself.viewの中に沢山あったとして、それらをまとめて処理したい場合は次のように書くことができる。





UIImageViewやUIButtonをtintColorで色を変えたい


通常、UIImageView や UIButtonの画像の色は、tintColor を指定しても変えることができない。
画像をα値だけでレンダリングするように設定してあげれば UIImage.RenderingMode.alwaysTemplate tintColorが効くようになる。





ナビゲーションバーの色を変えたい


ナビゲーションバーの色は、それぞれ次のように定義されている。


文字の色は、NSAttributedString を使って設定する。


ちなみに UIBarButtonItemtintColor でも変ることができる。
closeItem.tintColor = .white

また、ナビゲーションバーの色が少し薄い場合は、次のようにして対処する。
self.navigationController?.navigationBar.isTranslucent = false



テーブルセルの背景色を変えたい


UITableViewCell の背景色は、次のようにUITableViewのdelegateで変える。





MD5ハッシュ値の生成したい


こちらの記事を参考にさせていただいた。
CommonCrypto モジュールをインポートする必要がある。


Swift4で動作確認済み。

Stringextension しているので、使う時は "hogehoge".md5 のようにして変換することができる。



iOSの設定アプリへアクセスしたい


iOSの設定アプリの中の、自分のアプリの設定画面へショートカットできる。






数秒後に遅らせて実行させたい


DispatchQueue.main.asyncAfter を使えば、次のように遅延処理を簡単に書くことができる。





メインスレッドで実行したい


非同期処理の後にViewなどのUIを操作しようとするとクラッシュする。UIはメインスレッドで実行しなければならないからだ。
DispatchQueue.main.async を使ってメインスレッド内で実行するようにしよう。





クロージャでコールバック処理したい


ネットワーク越しに非同期でデータを取ってきて、その後にViewなどにデータを反映したい場合によく使うワザ。
completion(Int) -> Void のようなクロージャで定義する。ネットワーク処理などを書いて、成功したら completion(rank) で呼び出す。



使う側はこんな感じ。
fetchYourRank(leaderboardId: leaderboardId, completion: { rank in
    self.yourLankLabel.text = "あなたの順位は\(rank)位です"
})

引数にクロージャを定義することで分かりやすいコールバック処理を書くことができる。



画面の向きが変わったらイベントを検知したい



UIDeviceOrientation には isFlatisValidInterfaceOrientation などもあることに注意。



端末がiPadかどうか判定したい


UIDevice.current.userInterfaceIdiomで判別できる。三項演算子と合わせるとスマートに書ける。





デバッグ時とリリース時で動作を変えたい


次のようにして実現できる。



ただしこのDEBUGの定義を使えるようにするためには、Builid SettingsOther Swift FlagsでDebugの項目のみに-D DEBUGと指定する必要がある。

大事なことなのでもう一度言うが、必ずDebugの項目のみにパラメータを入れるように。





シングルトンを実装したい


次のように static を使って宣言する。
使う時は Hoge.shared.doSomething() のように shared を経由して関数を呼び出すこと。
init をオーバーライドして private にしておくと shared 忘れがなくてよい。






UIColorに独自カラーを追加したい


こんな感じでUIColorを拡張する。


ポイントは関数ではなく変数として定義してclassを指定すること。すると次のようにシステムカラーと同じような扱いで簡単に指定することができる。

textLabel.textColor = .textLightColor




UITalbeViewの最下部にスクロールしたい


最下部にスクロールするにはscrollToRowを使うが、tableView.reloadData() 後すぐに実行すると正しくスクロールできない。
タイマーでタイミングを少しずらすことでうまくいった。





メソッドを一度だけ実行したい


viewDidLayoutSubviewsなど何度も呼び出されてしまうメソッド内で、一度だけ実行したい処理があった場合に以下のような書き方をしていた。
これだと毎回フラグを宣言、条件分岐するのは面倒だし、可読性がよくないなと思っていた。



クロージャーとlazyを使ったスマートな書き方を見つけたので、参考にさせていただいた。
https://qiita.com/codelynx/items/f0243d631f2448e89026



こちらの方が可読性が上がる。

他にもいろいろな書き方がいろいろあるようだ。

クロージャー(Closures)は名前のない関数で変数として扱われる。
lazy(lazy stored property)は、参照されるときに初めて初期値が設定されるプロパティ。



UILongPressGestureRecognizerは二回呼ばれてしまう


let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPressedButton))
button.addGestureRecognizer(longPressRecognizer)


こんな感じで登録したlongPressedButton関数は二回呼ばれる。
アラートなど呼び出す時は二度呼ばれてしまうので注意が必要。
UIGestureRecognizerのstateで下記のように切り分ける。





メソッドチェーンの返り値を使わない時のwarningを消したい


メソッドチェーンを実装しようとした時に、返り値を使わない場合が多々ある。
Xcodeは関数の返り値を使わないと丁寧にwarningを出してくれるが、warningだらけになってしまうので対処したかった。
結論としては、@discardableResult アノテーションを付ければよいだけだった。







あなたにおすすめ