SwiftUI ButtonStyle - 如何检查按钮是否被禁用或启用? [英] SwiftUI ButtonStyle - how to check if button is disabled or enabled?

查看:67
本文介绍了SwiftUI ButtonStyle - 如何检查按钮是否被禁用或启用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要在 SwiftUI 中设置按钮样式,根据我的理解,您扩展 ButtonStyle 并实现 func makeBody(configuration: Self.Configuration) ->一些视图,您可以在其中开始对 configuration.label 应用修改,这是对 Button 视图的引用.

现在,除了 label 字段之外,ButtonStyle.Configuration 还有一个用于 isPressed 的布尔字段,但这似乎就是全部.

如何检查按钮是启用还是禁用?

例如,我想在按钮周围画一个边框,如果按钮启用,我希望边框为蓝色,如果禁用,则边框为灰色.

我的第一个猜测是这样的:

 func makeBody(configuration: Self.Configuration) ->一些视图{配置标签.覆盖(RoundedRectangle(cornerRadius: 4).stroke(configuration.isEnabled ? Color.blue : Color.gray, lineWidth: 1).padding(8))}

但是没有 isEnabled 字段.

Apple 提供的 PlainButtonStyle 显然可以访问此信息,因为头文件中的文档注释声明它说该样式可能会应用视觉效果来指示按下的、聚焦的或按钮的启用状态.'

////一个 `Button` 样式,在空闲时不会对其内容进行样式或装饰.//////样式可以应用视觉效果来指示按下、聚焦、///或按钮的启用状态.@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)公共结构PlainButtonStyle : PrimitiveButtonStyle {.....

有没有办法访问这些信息?

在您建议关闭此问题之前,请阅读以下内容:

不久前有人问过类似的问题.这个问题没有说明任何上下文.

这里我有一个特定的上下文:创建一个通用的可重用按钮样式.

那里提供的答案是不够的.我不能指望人们将禁用状态传递给样式构造函数.重复工作太多了.

你能想象人们是否必须以这种方式编写代码:

Button() { .... }.disabled(someExprssion).buttonStyle(MyCustomStyle(disabled: someExpression))

显然这是不可取的.

同样很明显,Apple 提供的样式可以访问信息,而无需人们再次将禁用状态传递给样式.

如果您关闭问题,您将永远阻止任何人在 StackOverflow 上对此问题提供有用的答案.

在您提议关闭之前请重新考虑.

我猜测,如果您可以获得 Button 视图的 EnvironmentValues.isEnabled,那么它可能是正确的值.

所以另一种提问方式是:是否有可能在 SwiftUI 中获得您没有定义自己的视图的环境?

解决方案

感谢这个博客,我找到了答案:https://swiftui-lab.com/custom-styling/

您可以通过创建包装视图并在样式结构中使用它来从环境中获取启用状态:

struct MyButtonStyle: ButtonStyle {func makeBody(configuration: ButtonStyle.Configuration) ->一些视图{MyButton(配置:配置)}结构我的按钮:查看{让配置:ButtonStyle.Configuration@Environment(.isEnabled) 私有变量 isEnabled: Boolvar主体:一些视图{configuration.label.foregroundColor(isEnabled ? Color.green : Color.red)}}}

这个例子演示了如何获取状态并使用它来改变按钮的外观.如果按钮被禁用,它会将按钮文本颜色更改为红色,如果启用则将其更改为绿色.

To style a button in SwiftUI, according to my understanding, you extend ButtonStyle and implement func makeBody(configuration: Self.Configuration) -> some View within which you start applying modifications to the configuration.label which is a reference to the Button view.

Now, besides the label field, ButtonStyle.Configuration has a boolean field for isPressed, but that's seems to be all.

How do I check if the button is enabled or disabled?

For example, I want to draw a border around the button, and I want the border to be blue if the button is enabled and gray if disabled.

My first guess is something like this:

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .overlay(
                RoundedRectangle(cornerRadius: 4).stroke(configuration.isEnabled ? Color.blue : Color.gray, lineWidth: 1).padding(8)
            )
    }

But there's no isEnabled field.

The Apple-supplied PlainButtonStyle obviously has access to this information, as the doc comment in the header file that declares it says 'The style may apply a visual effect to indicate the pressed, focused, or enabled state of the button.'

/// A `Button` style that does not style or decorate its content while idle.
///
/// The style may apply a visual effect to indicate the pressed, focused,
/// or enabled state of the button.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public struct PlainButtonStyle : PrimitiveButtonStyle {
.....

Is there a way to access this information?

EDIT:

Before you suggest closing this question, please read this:

There's a similar question asked a while ago. That question does not specify any context.

Here I have a specific context: creating a generic reusable button style.

The answer provided there does not suffice. I can't expect people to pass the disabled state to the style constructor. That's too much duplication of effort.

Can you imagine if people have to write code this way:

Button() { .... }.disabled(someExprssion).buttonStyle(MyCustomStyle(disabled: someExpression))

Clearly that's not desireable.

Also clearly the Apple supplied style has access to the information without requiring people to pass the disable state again to the style.

If you close the question, you will forever prevent anyone from providing a useful answer to this question on StackOverflow.

Please reconsider before you propose closing.

EDIT2:

I have a guess that if you can get the EnvironmentValues.isEnabled of the Button view then it might be the right value.

So another way to ask the question is: is it possible in SwiftUI to get the environment of a view that you didn't define yourself?

解决方案

I found the answer thanks to this blog: https://swiftui-lab.com/custom-styling/

You can get the enabled state from the environment by creating a wrapper view and using it inside the style struct:

struct MyButtonStyle: ButtonStyle {
    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.foregroundColor(isEnabled ? Color.green : Color.red)
        }
    }
}

This example demonstrates how to get the state and use it to change the appearance of the button. It changes the button text color to red if the button is disabled or green if it's enabled.

这篇关于SwiftUI ButtonStyle - 如何检查按钮是否被禁用或启用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆