开发者社区 问答 正文

SwiftUI ButtonStyle-如何检查按钮是否已禁用或启用?

要在SwiftUI中设置按钮的样式,根据我的理解,您可以扩展ButtonStyle
和实施

func makeBody
(configuration: Self.Configuration) -> some View```  
在其中,您开始将修改应用到configuration.label,它是对```
Button```  
视野。

现在,除了label场,ButtonStyle.Configuration有一个布尔字段isPressed但似乎仅此而已。

如何检查该按钮是否已启用或禁用?

例如,我希望在按钮周围绘制一个边框,如果启用了该按钮,则希望边框为蓝色,如果禁用,则希望边框为灰色。

我最初的猜测是这样的:

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

苹果供应```
PlainButtonStyle```  
显然可以访问这些信息,因为头文件中的doc注释声明“样式可以应用可视效果来指示按钮的按下、聚焦或启用状态”。

/// 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 { .....

有办法获取这些信息吗?

编辑:

在建议结束这个问题之前,请阅读以下内容:

不久前也有一个类似的问题。这个问题没有具体说明任何情况。

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

如果有这样的答案是不够的。我不能期望人们将禁用状态传递给样式构造函数。太重复了。

如果人们不得不这样写代码,你能想象吗:

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


显然这是不可取的。

而且,很明显,Apple提供的样式可以访问信息,而不需要用户将禁用状态再次传递给样式。

如果您关闭这个问题,您将永远阻止任何人在StackOverflow上为这个问题提供有用的答案。

在提议结束之前请重新考虑。

展开
收起
游客5akardh5cojhg 2019-12-04 16:53:06 1114 分享 版权
阿里云 AI 助理回答

在SwiftUI中,直接通过ButtonStyle来访问按钮的启用状态(isEnabled)并不直观,因为风格配置本身并不直接提供这个信息。但是,您可以通过一种间接的方式来实现根据按钮的启用状态改变样式的目的,尽管这可能不如直接访问一个布尔属性那样直接。

一种方法是创建一个自定义视图修饰器(ViewModifier),该修饰器接收一个是否启用的参数,并基于此参数调整边框颜色。然后,在应用您的自定义ButtonStyle时,可以利用SwiftUI的组合能力,让按钮内容在被包装时传递其启用状态给修饰器。这里是一个示例:

struct ButtonEnabledBorder: ViewModifier {
    let isEnabled: Bool

    func body(content: Content) -> some View {
        content
            .overlay(
                RoundedRectangle(cornerRadius: 4)
                    .stroke(isEnabled ? Color.blue : Color.gray, lineWidth: 1)
                    .padding(8)
            )
    }
}

struct EnabledAwareButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            // 这里我们使用环境对象或绑定值来传递启用状态,但实际中需要更复杂的逻辑来动态获取
            .modifier(ButtonEnabledBorder(isEnabled: true)) // 实际应用中需替换为正确的启用状态来源
    }
}

然而,上述代码中的.modifier(ButtonEnabledBorder(isEnabled: true))部分面临一个问题:如何动态地知道按钮的启用状态?由于SwiftUI的ButtonStyle不直接暴露按钮的启用状态,我们需要采取一种变通的方法。一种可能的方案是不在ButtonStyle内部处理这个逻辑,而是让你的应用逻辑在构建按钮时动态决定是否应用特定的样式或者直接修改内容视图。

例如,你可以在应用样式之前,先用一个自定义的视图修饰器包装按钮的内容,这个修饰器负责根据按钮的disabled状态调整外观。然后,你可以将这个已经修饰过的视图作为按钮的内容传入,这样你的样式就可以基于内容视图的当前状态进行渲染了。

但是,要注意的是,这种方法仍然不够优雅,因为它要求你在每次使用按钮时都明确考虑并传递启用状态。理想情况下,我们希望有一个更简洁、更自动化的解决方案,但这受限于当前SwiftUI框架提供的API。

鉴于Apple自家的PlainButtonStyle能够做到这一点,这表明内部可能有更深层次的机制来检测状态变化,但这些细节并未公开给开发者直接使用。因此,目前最实用的建议仍然是在应用样式时显式地管理按钮的状态,尽管这确实增加了代码的重复性。对于这个问题,如果有新的SwiftUI更新提供了更好的解决方案,社区和文档将会是获取最新信息的最佳途径。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: