SwiftUI:禁用具有自定义 ButtonStyle 的 NavigationLink 的最佳方法
Posted
技术标签:
【中文标题】SwiftUI:禁用具有自定义 ButtonStyle 的 NavigationLink 的最佳方法【英文标题】:SwiftUI: Optimal way to disable NavigationLink which has a custom ButtonStyle 【发布时间】:2020-11-14 18:39:49 【问题描述】:我有一个具有自定义 ButtonStyle 的导航链接:
NavigationLink(destination: NextScreen())
Text("Next")
.buttonStyle(CustomButtonStyle(disabled: !isValidPassword))
我的 CustomButtonStyle 看起来像这样:
@State var disabled = false
func makeBody(configuration: Self.Configuration) -> some View
configuration.label
.frame(minWidth: 0, maxWidth: .infinity)
.padding(15)
.foregroundColor(.white)
.background(disabled ? .black : .gray)
.cornerRadius(40)
.disabled(disabled) // this has no effect when inside a NavigationLink
用户输入密码时,用户界面会正确更新。
您可以看到我禁用了 ButtonStyle 内的按钮,但这并不妨碍用户仍然点击 NavigationLink 以转到 NextScreen()
。
为了解决这个问题,我最终这样做了:
NavigationLink(destination: SignupStepBirthdayView())
Text("Next")
.buttonStyle(BobbleUpButtonStyle(disabled: !isValidPassword))
.disabled(!isValidPassword)
这似乎效率低下,因为我将禁用状态传递给按钮样式以更新 UI,然后不得不禁用实际的 NavigationLink
。
有没有更好的方法来做到这一点?
【问题讨论】:
ButtonStyle 是关于按钮的视觉呈现(在这种情况下是链接),而不是关于行为。通过自定义样式,您禁用了 NavigationLink 内的文本标签,而不是链接本身 - 它应该在外部禁用,就像您已经做的那样。 【参考方案1】:我将向您展示简单的方法,无需使用@Bingding 或@State
首先,创建您的按钮样式:
struct CustomButtonStyle: ButtonStyle
public func makeBody(configuration: ButtonStyle.Configuration) -> some View
MyButton(configuration: configuration)
struct MyButton: View
let configuration: ButtonStyle.Configuration
@Environment(\.isEnabled) private var isEnabled: Bool
var body: some View
configuration.label
.frame(minWidth: 0, maxWidth: .infinity)
.padding(15)
.foregroundColor(.white)
.background(isEnabled ? Color.blue : Color.gray)
.cornerRadius(40)
.disabled(!isEnabled)
然后,将其作为任何 SwiftUI 组件禁用:
struct ContentView: View
@State var text: String = ""
var body: some View
NavigationView
VStack
TextField("Enter your text", text: $text)
NavigationLink(destination: NextScreen())
Text("Next")
.buttonStyle(CustomButtonStyle())
.disabled(text.isEmpty)
【讨论】:
【参考方案2】:您必须在 CustomButtonStyle 中使用 Binding 而不是 State
@Binding var disabled : Bool
这会在您的 ContentView 中发生变化
@State var isValidPassword: Bool = true
还有:
.buttonStyle(BobbleUpButtonStyle(disabled: $isValidPassword))
【讨论】:
以上是关于SwiftUI:禁用具有自定义 ButtonStyle 的 NavigationLink 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸
具有自定义数据结构的 SwiftUI 列表,每个循环都嵌套 [关闭]