// First create a button style that gets the isEnabled value injected
struct MyButtonStyle: ButtonStyle {
private let isEnabled: Bool
init(isEnabled: Bool = true) {
self.isEnabled = isEnabled
}
func makeBody(configuration: Configuration) -> some View {
return configuration
.label
.background(isEnabled ? .green : .gray)
.foregroundColor(isEnabled ? .black : .white)
}
}
// Then make a ViewModifier to inject the state
struct MyButtonModifier: ViewModifier {
@Environment(.isEnabled) var isEnabled
func body(content: Content) -> some View {
return content.buttonStyle(MyButtonStyle(isEnabled: isEnabled))
}
}
// Then create a convenience function to apply the modifier
extension Button {
func styled() -> some View {
ModifiedContent(content: self, modifier: MyButtonModifier())
}
}
// Finally, try out the button and watch it respond to it's state
struct ContentView: View {
var body: some View {
Button("Test", {}).styled().disabled(true)
}
}
5条答案
按热度按时间dluptydi1#
在视图中,如果希望对
.disabled(true)
设置的状态做出React,可以使用:@Environment(\.isEnabled) var isEnabled
由于可以从View或ViewModifier中使用环境,因此可以使用该环境根据从外部设置的状态来更改视图的布局属性。
遗憾的是,
ButtonStyle
不能直接使用@Environment
,但您可以使用ViewModifier
将环境值注入ButtonStyle
,以便使用ButtonStyle
中的值:您可以使用此方法向ButtonStyle中注入其他内容,如大小、类别和主题。
我将其与定制样式枚举一起使用,该枚举包含我们的设计系统中找到的按钮样式的所有风格。
myss37ts2#
从视图外部,您应该知道是否使用了
.disabled(true)
修改器。在视图内部,您可以使用
@Environment(\.isEnabled)
获取该信息:i7uaboj43#
SwiftUI的整个理念,是为了避免重复真相的来源。你需要以不同的方式思考,并思考真理的来源在哪里。这是您需要查看按钮状态的地方。而不是从按钮本身。
在《数据流通过SwiftUI》中,他们在30:50分钟解释说,每一条数据都有单一的真理来源。如果您的按钮从某个@Binding、@State、@Environmental Object等获取其状态,则if语句也应该从同一位置获取该信息,而不是从按钮获取。
62o28rlo4#
简而言之:只需在结构中使用:
按钮样式:
用法:
源代码:
cngwdvgl5#
正如其他开发人员所提到的,SwiftUI的主要思想是用户界面与数据保持同步。您可以通过许多不同的方式执行此操作。这包括@State、@Environment Object、@Binding等。