首页 > 解决方案 > SwiftUI ButtonStyle 在 iOS 14.4 上忽略 isEnabled 环境变量,适用于 iOS 14.5+

问题描述

我有以下 SwiftUI ButtonStyle

public struct PrimaryButton: ButtonStyle {
    private let type: ButtonType
    @Environment(\.isEnabled) private var isEnabled

    public init() {
    }

    public func makeBody(configuration: Configuration) -> some View {
        configuration
            .label
            .font(.callout)
            .foregroundColor(textColor)
            .padding(padding)
            .background(backgroundColor)
            .clipShape(RoundedRectangle(cornerRadius: 4,
                                        style: .continuous))
            .opacity(configuration.isPressed ? 0.5 : 1)
    }

    private var padding: EdgeInsets {
            return EdgeInsets(top: 16,
                              leading: 16,
                              bottom: 16,
                              trailing: 16)
    }

    private var backgroundColor: Color {
        isEnabled ? .blue : .gray
    }

    private var textColor: Color {
        isEnabled ? Color.white : .gray
    }
}

以及以下预览代码:

struct ButtonStyle_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            SwiftUI.Button(action:{}, label: {
                Text(verbatim: "Primary")
            }).buttonStyle(PrimaryButton())

            SwiftUI.Button(action:{}, label: {
                Text(verbatim: "PrimaryDisabled")
            }).buttonStyle(PrimaryButton())
            .disabled(true)
        }
        .padding()
    }
}

令人惊讶的是,当我尝试在不同的 iOS 版本中预览相同的代码时,我得到了完全不同的结果: 在此处输入图像描述 在此处输入图像描述

iOS 14.4、Xcode 12.2 - 不正确

在此处输入图像描述

iOS 14.5、Xcode 12.5.1 - 正确

在此处输入图像描述

请注意,在这两种情况下,按钮在禁用时都不会对更改做出反应。在 iOS 14.4 上它似乎已启用,但无法按下它。

似乎该@Environment(\.isEnabled)值被忽略并简单地默认为true. 我有一个类似的问题@Environment(\.horizontalSizeClass),它在哪里表现得好像它是nil,不是.regular和不是.compact。在 iOS 14.5 中,此错误已修复,但如何将其“向后移植”到 iOS 14.4?

  1. iOS 14.4 和 iOS 14.5 之间出现这种不一致行为的原因是什么?
  2. 我的代码中是否有任何原因可能导致它?
  3. iOS 14.4 上的任何解决方案?
  4. 如果它是一个 SwiftUI 错误,是否可以以PrimaryButton某种方式重写按钮仍然可以反映其状态的变化(启用/禁用)的代码。

标签: iosswiftbuttonswiftuiswiftui-environment

解决方案


推荐阅读