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

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

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

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

# 角丸のボタンを作る

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

↓

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

# ボタン押す時の処理

```swift
buton.addAction(action, for: .touchUpInside)
```

↓

```swift
buton.addAction(action, for: .primaryActionTriggered)
```

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

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

```swift
index < items.count
```

↓

```swift
index < items.endIndex
```

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

```swift
items.contains(item)
```

を使う

# 数字の文字列変換とか

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

詳しくは

https://qiita.com/treastrain/items/e0e9c3e9f517fa20ad08

# UITableView

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

↓

```swift
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を使う

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

↓

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

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

# UIBarButtonItemのラベル

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

↓

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

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

# UIColor.white,black

```swift
let textColor = UIColor.black
```

```swift
let textColor = UIColor.label
```

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

# UIColor.systemBlue

```swift
button.tintColor = UIColor.systemBlue
```

↓

```swift
button.tintColor = UIColor.tintColor
```

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

# アイコン

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

↓

```swift
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を再代入できない状態にできる。

---

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