我如何知道SwiftUI按钮是否已启用?

iOS*_*com 3 swift swiftui

isEnabledSwiftUI按钮没有属性。我如何知道它是否启用?

在常规的UIKit中,我只会做

if button.isEnabeld == true {
} else {
}
Run Code Online (Sandbox Code Playgroud)

但是没有等效的SwiftUI。

小智 15

在视图中,如果您希望对由 设置的状态做出反应.disabled(true),您可以使用: @Environment(\.isEnabled) var isEnabled

由于可以在 View 或 ViewModifier 中使用环境,因此可以使用它根据从外部设置的状态来更改视图的布局属性。

不幸的是,ButtonStyle不能直接使用@Environment,但您可以使用 aViewModifier将环境值注入 aButtonStyle以便使用a中的值ButtonStyle


// 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用此方法将其他内容注入 ButtonStyle,例如大小类别和主题。

我将它与自定义样式枚举一起使用,该枚举包含在我们的设计系统中找到的所有按钮样式。


小智 12

从外部看,您应该知道是否使用了.disabled(true)修饰符。

您可以从视图内部@Environment(\.isEnabled)获取该信息:

struct MyButton: View {
    let action: () -> Void
    @Environment(\.isEnabled) private var isEnabled

    var body: some View {
        Button(action: action) {
            Text("Click")
        }
        .foregroundColor(isEnabled ? .green : .gray)
    }
}

struct MyButton_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            MyButton(action: {})
            MyButton(action: {}).disabled(true)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


kon*_*iki 9

SwiftUI的整体思想是避免重复真理的来源。您需要以不同的方式思考,并考虑真相的来源。这是您需要找出按钮状态的地方。不是来自按钮本身。

在“数据流通过SwiftUI”,在分30:50,他们解释说,每个数据都有一个单一的真理的来源。如果您的按钮从某些@ Binding,@ State,@ EnvironmentObject等获取其状态,则if语句也应该从同一位置(而不是从按钮)获取该信息。