SwiftUI 有一些Button初始值設定項,但所有這些初始值設定項都需要 aString或some View作為引數與action.
但是,按鈕的外觀也可以在ButtonStyles的幫助下進行自定義,s 可以為其添加自定義視圖。
讓我們考慮一個帶有以下圖示的復制按鈕:

我為按鈕制作的樣式如下所示:
struct CopyButtonStyle: ButtonStyle {
init() {}
func makeBody(configuration: Configuration) -> some View {
let copyIconSize: CGFloat = 24
return Image(systemName: "doc.on.doc")
.renderingMode(.template)
.resizable()
.frame(width: copyIconSize, height: copyIconSize)
.accessibilityIdentifier("copy_button")
.opacity(configuration.isPressed ? 0.5 : 1)
}
}
它作業得很好,但是,我必須Button在呼叫站點用空字串初始化:
Button("") {
print("copy")
}
.buttonStyle(CopyButtonStyle())
那么,問題是如何去掉按鈕初始化引數中的空字串?
潛在解決方案
我能夠創建一個簡單的擴展來完成我需要的作業:
import SwiftUI
extension Button where Label == Text {
init(_ action: @escaping () -> Void) {
self.init("", action: action)
}
}
呼叫站點:
Button() { // Note: no initializer parameter
print("copy")
}
.buttonStyle(CopyButtonStyle())
但是很好奇,我是否Button錯誤地使用了結構并且已經有一個用例,以便我可以擺脫這個擴展。
uj5u.com熱心網友回復:
比進行ButtonStyle配置更簡單的方法是直接傳入標簽:
Button {
print("copy")
} label: {
Label("Copy", systemImage: "doc.on.doc")
.labelStyle(.iconOnly)
}
這也帶來了一些好處:
- 默認情況下,按鈕是藍色的,表示它可以被點擊
- 您當前擁有的影像沒有奇怪的拉伸
- 無需實作按下時不透明度的變化方式
您也可以將其重構為自己的視圖:
struct CopyButton: View {
let action: () -> Void
var body: some View {
Button(action: action) {
Label("Copy", systemImage: "doc.on.doc")
.labelStyle(.iconOnly)
}
}
}
像這樣呼叫:
CopyButton {
print("copy")
}
整體看起來干凈多了。
uj5u.com熱心網友回復:
這是您嘗試執行的操作的正確方法,您不需要為每種 Button 都創建一個新的 ButtonStyle,您可以只創建一個并將其重用于您想要的任何其他 Button。我也解決了你的影像拉伸問題.scaledToFit()。
struct CustomButtonView: View {
let imageString: String
let size: CGFloat
let identifier: String
let action: (() -> Void)?
init(imageString: String, size: CGFloat = 24.0, identifier: String = String(), action: (() -> Void)? = nil) {
self.imageString = imageString
self.size = size
self.identifier = identifier
self.action = action
}
var body: some View {
return Button(action: { action?() } , label: {
Image(systemName: imageString)
.renderingMode(.template)
.resizable()
.scaledToFit()
.frame(width: size, height: size)
.accessibilityIdentifier(identifier)
})
.buttonStyle(CustomButtonStyle())
}
}
struct CustomButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
return configuration.label
.opacity(configuration.isPressed ? 0.5 : 1.0)
.scaleEffect(configuration.isPressed ? 0.95 : 1.0)
}
}
用例:
struct ContentView: View {
var body: some View {
CustomButtonView(imageString: "doc.on.doc", identifier: "copy_button", action: { print("copy") })
}
}
uj5u.com熱心網友回復:
您可以EmptyView用于標簽,例如
Button(action: { // Note: no initializer parameter
print("copy")
}, label: { EmptyView() })
.buttonStyle(CopyButtonStyle())
但從重用和代碼可讀性的角度來看,將它包裝在自定義按鈕型別(如其他答案中所示)更可取。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/391049.html
