🎨

UIButton.Configuration その3 〜なんでもできちゃいます

に公開

UIButton Configurationの3回目。
ややこしめの事柄について。

画像としてSF Symbolを使う場合の大きさ指定

画像としてSF Symbolを使う場合、 UIImage.SymbolConfiguration を使って大きさを指定できます。

configuration.image = UIImage(systemName: "swift")
configuration.preferredSymbolConfigurationForImage = 
    UIImage.SymbolConfiguration(pointSize: 30) 

状態による変化を指定する

「ボタンを押した」などの状態によってタイトルや配色を変化させるのは、状態変化時にクロージャを走らせます。クロージャはこのように書きます。

{ button in
    switch button.state {
    case [.selected, .highlighted]:
        button.configuration?.title = "Highlighted Selected"
    case .selected:
        button.configuration?.title = "Selected"
    case .highlighted:
        button.configuration?.title = "Highlighted"
    case .disabled:
        button.configuration?.title = "Disabled"
    default:
        button.configuration?.title = "Normal"
    }
}

状態変化のタイミングで上のクロージャを走らせるには、このクロージャを次のように configurationUpdateHandler に設定します。

let handler: UIButton.ConfigurationUpdateHandler = { button in
    switch button.state {
	//個々の設定
    }
}
button.configurationUpdateHandler = handler

これはボタンを押したときにも走りますが、ソース上で isEnabled を設定したときにも走るので基本的な状態変化に対応しているようです。

任意のタイミングでConfigurationをUpdateする

ボタンへの押下操作ではなく別の理由によりボタンの見た目を変える場合、updateしたいタイミングで setNeedsUpdateConfiguration() メソッドを呼ぶ。それに従い configurationUpdateHandler が実行される。

使用例

var checkingOut = false {
    didSet {
	checkoutButton.setNeedsUpdateConfiguration()
    }
}

ActivityIndicator

showsActivityIndicatortrue にすると、画像の部分がくるくるに変わります。

config.showsActivityIndicator = true

ボタンを押したときに走る処理の登録

Configurationの範囲から外れますが、従来のaddTarget方式に変わる新しいやり方がiOS14から追加されました。

button.addAction(
	UIAction { _ in
		print("You tapped the button!")
	},
	for: .touchUpInside
)

デフォルトの書き方を提案する

非常に多くの設定項目があったが、最後にシンプルなひながたのようなものを作ってみたい。

画像なし

var configuration = UIButton.Configuration.filled()
configuration.title = "タイトル"
//configuration.buttonSize = .medium
//configuration.cornerStyle = .capsule

後は、ボタンの役目に応じて plain gray tinted filled を変えたり、大きさを変える。
capsuleが有効な場合ならcapsuleを選択するのも良い。

画像あり

var configuration = UIButton.Configuration.filled()
configuration.title = "タイトル"
configuration.image = UIImage(systemName: "doc")
configuration.imagePadding = 10.0
configuration.imagePlacement = .leading
configuration.buttonSize = .large

画像ありではサイズをlargeにするのが余白に余裕が出来て良い。また、imagePaddingがデフォルトでは少ないので少々開けておくのが良い。

使わないもの

新しいやり方をするときに従来のものを使わないように意識する必要がすこしあるかなと思います。併用すると方針が混乱しますので。

その1

https://zenn.dev/samekard_dev/articles/64d8f1578a7bb6

その2

https://zenn.dev/samekard_dev/articles/c737dee4bcc5f6

Discussion