为啥视图修饰符不能接受不可变变量?

Posted

技术标签:

【中文标题】为啥视图修饰符不能接受不可变变量?【英文标题】: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

非常感谢您。

【问题讨论】:

【参考方案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,感谢您的解决方案。供其他人参考,此解决方案也有效。我标记了另一个,因为我设置了一个参数,因为我要重用它。所以更接近我的初衷。

以上是关于为啥视图修饰符不能接受不可变变量?的主要内容,如果未能解决你的问题,请参考以下文章

const修饰符在不同位置带来的效应

final修饰的变量引用不能变还是对象不可变

a.变量及基本数据结构

第十四节——可变参数

不可变对象

如何创建一个不可变类