【问题标题】:Why view modifier can't take in immutable variable?为什么视图修饰符不能接受不可变变量?
【发布时间】:2021-02-22 09:17:17
【问题描述】:

我做了一个按钮修饰符,背景颜色应该根据它是否被点击而改变。但我抱怨 viewModifier 的输入参数是不可变的。

我在 btnBkColor 上出现错误

.modifier(ActionButtonType(bkColor: btnBkColor))

错误信息:

不能对不可变值使用可变 getter:'self' 是不可变的

这是我的简化代码:

struct MyView: View {
@State private var cond = false
private lazy var btnBkColor: Color = cond ? Color.orange : Color.green
var body: some View {
              Button(action: { cond.toggle() }, label: {
              Text(cond ? "A" : "B")
  })
  .modifier(ActionButtonType(bkColor: btnBkColor))
}
}

修饰符:

struct ActionButtonType: ViewModifier {
    let bkColor: Color
    func body(content: Content) -> some View {
        content
            .background(bkColor)
    }
}

ViewModifier里面只得到btnBkColor,没有设置btnBkColor,不明白为什么输入参数不能不可变?

我尝试过但无济于事:

  • 将 let 更改为 var
  • 在 btnBkColor 前面添加@State

非常感谢您。

【问题讨论】:

    标签: swift swiftui viewmodifier


    【解决方案1】:

    使用计算属性。不能将self变量直接用于其他变量。

    struct MyView: View {
        @State private var cond = false
        
        private var btnBkColor: Color {
            cond ? Color.orange : Color.green
        } // <--Here
        
        var body: some View {
            Button(action: { cond.toggle() }, label: {
                Text(cond ? "A" : "B")
            })
            .modifier(ActionButtonType(bkColor: btnBkColor))
        }
    }
    

    【讨论】:

    • 使用您的第二个解决方案,btnBkColor 不会在 cond 更新时更新。
    • @DávidPásztor。哦,是的。
    • 嗨,你如何声明 btnBkColor 很酷,我尝试了 private var btnBkColor: Color = (cond ? Color.orange : Color.green) 但得到“不能使用实例成员 'cond' 的错误在属性初始化器中;属性初始化器在 'self' 可用之前运行”它适用于您的语法!
    • 使用大括号并删除等号:``` private var btnBkColor: Color { cond ? Color.orange : Color.green }```
    【解决方案2】:

    最简单的情况,也是 SwiftUI 代码中最常使用的,是使用状态依赖内联修饰符(这在需要时/如果需要也可以动画化)

    struct MyView: View {
      @State private var cond = false
    
      var body: some View {
          Button(action: { cond.toggle() }, label: {
             Text(cond ? "A" : "B")
          })
          .modifier(ActionButtonType(bkColor: cond ? Color.orange : Color.green))
      }
    }
    

    【讨论】:

    • 嗨@Asperi,感谢您的解决方案。供其他人参考,此解决方案也有效。我标记了另一个,因为我设置了一个参数,因为我要重用它。所以更接近我的初衷。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2021-05-02
    • 2020-03-29
    • 2019-12-14
    • 2011-10-07
    相关资源
    最近更新 更多