しみじみ勉強してきたのに、
なぜか簡単に作れないこういうボタン。
ので、少しやってみました。
🧑🏻💻 まず思いついた記述
便利な BorderdProminentButtonStyle()
に .overlay()
で 角丸枠線をのせます。
// borderProminent + overlay
Button {
} label: {
VStack {
Label("BorderedProminent", systemImage: "face.smiling")
Text(".overlay()")
.font(.caption)
}
.padding()
}
.buttonStyle(.borderedProminent)
.tint(.orange)
#if os(macOS)
.clipShape(.rect(cornerRadius: 16))
#endif
.overlay(RoundedRectangle(cornerRadius: 16).stroke(.gray))
macOS では角がずれる。
ので、clipShape()
しました。
気持ち悪いですね。
🧑🏻💻 よくある記述
この書き方が多いらしいです。
ラベル の View に modifier のチェイン。
// plain + label view modifiers
Button {
} label: {
VStack {
Label("Plain", systemImage: "face.smiling")
Text(".background(.orange, in: .rect(cornerRadius: 16))")
.font(.caption)
Text(".overlay()")
.font(.caption)
}
.foregroundStyle(.white)
.padding()
.background(.orange, in: .rect(cornerRadius: 16))
.overlay(RoundedRectangle(cornerRadius: 16).stroke(.gray))
}
.buttonStyle(.plain)
ButtonStyle は .plain
一択でしたが、
見た目も、ボタンを押したときの挙動も、
問題ないように見えます。
ただ、コードが長ったらしくなるので、
同様なボタンの数が増えると見通しが悪くなりそうです。
🧑🏻💻 カスタム ButtonStyle
ビルトインにあっても良さそうなのに。
押したときエフェクトは、BorderdProminentButtonStyle()
になるべく似せて ButtonStyle を作ります。
struct StrokeRoundedRectangleButtonStyle: ButtonStyle {
var cornerRadius: CGFloat
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundStyle(
.white.opacity(configuration.isPressed ? 0.75 : 1)
)
.padding()
.background(
.orange.opacity(configuration.isPressed ? 0.75 : 1),
in: .rect(cornerRadius: cornerRadius)
)
.overlay(
RoundedRectangle(cornerRadius: cornerRadius)
.stroke(.gray.opacity(configuration.isPressed ? 0.75 : 1))
)
}
}
extension ButtonStyle where Self == StrokeRoundedRectangleButtonStyle {
static var strokeRounded: Self { Self(cornerRadius: 16) }
}
ButtonStyle を作ってしまえば、あとは簡単にボタンに適用できます。
// custom style
Button {
} label: {
VStack {
Label("Custom Button Style", systemImage: "face.smiling")
Text("extension ")
.font(.caption)
}
}
.buttonStyle(.strokeRounded)
しかし、コード量は多い。
🧑🏻💻 まとめ
レイアウトの重なりの考え方として、この場合は、
角を丸くするのは .background()
で、
枠線はそれに合わせて .overlay()
する、
のが良さげに思えました。
あと、
iOS と macOS のコード共用は、シビアなレイアウトになると厳しいのですね!
👉 Customizing the Appearance and Interaction Behavior of Buttons | Fatbobman's Blog