よくButton("hogehoge", action: hoge)
みたいな書き方を見るけれどButton(action:label:)
とどう違うの?とかButtonStyle
とどう違うの?とか どうでも良いことについて の解説。
検証環境
Xcode: Version 14.2 (14C18)
iOS target: 16.2
検証コード
import SwiftUI
struct ContentView: View {
@State var isShowAlert = false
var body: some View {
ZStack {
Color.brown
VStack(spacing: 10) {
Button("title", action: showAlert)
.foregroundColor(.white)
.padding(.horizontal, 50.0)
.padding(.vertical, 10.0)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(.red)
)
Button(action: showAlert){
Text("title")
.foregroundColor(.white)
.padding(.horizontal, 50.0)
.padding(.vertical, 10.0)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(.red)
)
}
Button("title", action: showAlert)
.buttonStyle(.customStyle(color: .red))
}
.alert("メッセージ", isPresented: $isShowAlert) {
Button("Continue", role: .cancel) { }
}
}
}
private func showAlert() {
isShowAlert = true
}
}
struct CustomButtonStyle: ButtonStyle {
var color: Color = .blue
public func makeBody(configuration: CustomButtonStyle.Configuration) -> some View {
CustomButton(configuration: configuration, color: color)
}
struct CustomButton: View {
let configuration: CustomButtonStyle.Configuration
let color: Color
var body: some View {
return configuration.label
.foregroundColor(.white)
.padding(.horizontal, 50.0)
.padding(.vertical, 10.0)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(color)
)
.opacity(configuration.isPressed ? 0.3 : 1.0)
}
}
}
extension ButtonStyle where Self == CustomButtonStyle {
static func customStyle(color: Color = .red) -> some ButtonStyle {
CustomButtonStyle(color: color)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
検証結果
Buttonにモディファイアを付ける場合
paddingに反応しない。文字の領域をタップした時だけボタンが反応し、背景色が変わることはない。
init(action: label:)のlabelに装飾を付けた場合
今回はTextにモディファイアをつけた。
paddingに反応する。タップ時に背景色が薄くなるボタンらしい変化をする。
ButtonStyleで装飾を付けた場合
paddingに反応する。自分でタップした時の処理を指定しない場合は、色が薄くならない。
今回opacityを0.3に設定したが、本来のボタンはもう少し薄い…。
まとめ
Buttonにモディファイアを付けることは反応の面からも止めたほうが良いと思う。
手軽に作るならばinit(action:label:)
がベストだけれども、きちんと作るならばButtonStyleを使ったほうが良さそう。