LoginSignup
75

More than 1 year has passed since last update.

同じような処理だけどこっちの方がいいよってやつ

Last updated at Posted at 2021-12-19

Appleのプラットフォームでコードを書く上で、ほぼ同じ挙動でも用意されたAPIを使うとその後のOSアップデートや対応が楽に出来るというケースがあります。
これらを使うことで次のような恩恵があります。

  • OSアップデート時に追加される機能が変更なしで動くようになる
  • マルチプラットフォームでの修正が少なくなる
  • より標準に近い見た目になる
  • より実際の挙動を表現したコードになるので可読性が上がる

思いついたらどんどん追加します。

角丸のボタンを作る

let button = UIButton()
button.layer.cornerRadius = 6

let button = UIButton(configuration: .filled(), primaryAction: nil)

ボタン押す時の処理

buton.addAction(action, for: .touchUpInside)

buton.addAction(action, for: .primaryActionTriggered)

primaryActionTriggerdにすると、AppleTVとかでもいい感じに動く
この項目と関係ないですが、target/selectorのAPIはほとんどUIActionに置き換えられるようになっているので使っていないか確認してみると良いでしょう

indexが配列から溢れていないか

index < items.count

index < items.endIndex

startIndexも同様。countと比較するのは慣例であっても読みにくいコードになってしまう
範囲などの比較でも同じコードが利用できる
単純に要素が含まれているかは

items.contains(item)

を使う

数字の文字列変換とか

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.string(from: 10000) //10,000

詳しくは

UITableView

UITableView(frame: .null, style: .insetGrouped)

var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
UICollectionView(
    frame: .null,
    collectionViewLayout: UICollectionViewCompositionalLayout.list(using: configuration)
)

WWDC20かなんかでUITableViewじゃなくてUICollectionViewのlist使ってねって言ってた。

CGRect.zero

UIView(frame: .zero)

UIView(frame: .null)

zeroが0,0,0,0を指すのに比べて、nullは座標上に存在しないことを指す。
UIView(frame: .zero)をする時というのはAutoLayoutによって座標を決めたいケースなど、座標が存在しない初期状態を指したいことが大半なのでnullの方が正しいことが多い

レイアウト用の仮Viewを使う

let layoutView = UIView()
layoutView.backgroundColor = .clear
...
imageView.topAnchor.constraint(equalTo: layoutView.topAnchor).isActive = true

let layoutGuide = UILayoutGuide()
...
imageView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true

レイアウトのために仮のビューを作るのではなく、UILayoutGuideを作ると描画コストなどが下がる

UIBarButtonItemのラベル

UIBarButtonItem(title: "完了", image: nil, primaryAction: nil, menu: nil)

UIBarButtonItem(systemItem: .done, primaryAction: nil, menu: nil)

systemItemを使うと、ローカライズが自動的に行われる。
アプリのローカライズにおいて、システムの文言(キャンセルや完了など)はOSで使うものに揃える必要があるのでこれを使うと良いでしょう。

UIColor.white,black

let textColor = UIColor.black
let textColor = UIColor.label

よっぽどのことがない限り、色の指定しない方が良いです。
UIColorにはシステムで定義されたカラーがいくつも存在します。
これらを利用することでダークモードの対応やおそらくアクセシビリティの対応も自動的に行われます。

UIColor.systemBlue

button.tintColor = UIColor.systemBlue

button.tintColor = UIColor.tintColor

デフォルトのアクセントカラーはsystemBlueなのですが、アプリはグローバルな選択色を設定できるのでtintColorを使うのが正しいです。
Macの場合はユーザーがアクセントカラーを選べるのでこれ使うとそっちが反映されます。

アイコン

let image = UIImage(named: "plus.png")

let image = UIImage(systemImage: "plus")

アイコンは極力SFSymbolsを使った方がいいかなと自分は考えてます。
SFSymbolsを無視するのは自由ですが、その上で目の不自由な人に使いにくいアプリにしたり、ユーザーがせっかく覚えたアイコンの意味を蔑ろにするアプリを作るのはやめたいですね。(そのためのカスタムSFSymolsですが、それなりに作るのは大変です)

Xcodeを開くときのコマンド

$ open hoge.xcworkspace

$ xed .

必須の遅延代入

var value: Int!

lazy var value: Int = { preconditionFailure("valueに代入してから呼ぶこと") }()

lazyにすることで、代入前に呼ぶと前提条件例外であるpreconditionFailureが叩かれるようになる
また、nilを再代入できない状態にできる。


他、思いついたら追記します。
こんなのあるよっていうのがあればコメントで教えてください

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75