【问题标题】:Background of button not conditionally rendering按钮的背景没有条件渲染
【发布时间】:2019-12-25 01:28:48
【问题描述】:

基本上我有一个按钮,按下时我希望背景变成不同的颜色。为了做到这一点,我有一个要更改的对象,我打印出对象中 Bool 值的值并看到它的变化,但按钮的颜色没有变化。

布尔对象:

class dummyObject: Identifiable, ObservableObject {
    let objectWillChange = ObservableObjectPublisher()
    var id = UUID()
    var isSelected: Bool {
        willSet {
            objectWillChange.send()
        }
    }

    init(isSelected:Bool) {
        self.isSelected = isSelected
    }
}

查看:

struct SelectionView: View {
    var objs: [dummyObject] = [
        dummyObject.init(isSelected: false)
    ]


    var body: some View {
        HStack{
            ForEach(objs) { obj in
                Button(action: {
                    obj.isSelected.toggle()
                    print("\(obj.isSelected)")
                }) {

                    VStack {
                        Text("Test")
                            .foregroundColor(obj.isSelected ? Color.white : Color.gray)
                            .font(.caption)
                    }
                }.frame(width:55,height: 55)
                .padding()
                .background(obj.isSelected ? Color.red : Color.white)
                    .padding(.horizontal, 3)
                .clipShape(Circle()).shadow(radius: 6)
            }
        }.frame(minWidth: 0, maxWidth: .infinity)
        .padding()
    }
}

【问题讨论】:

    标签: swift button swiftui


    【解决方案1】:

    将您的Button 提取到其他视图中,其中obj@ObservedObject,一切都会正常工作:

    import SwiftUI
    import Combine
    
    class dummyObject: Identifiable, ObservableObject {
        let objectWillChange = ObservableObjectPublisher()
        var id = UUID()
        var isSelected: Bool {
            willSet {
                objectWillChange.send()
            }
        }
    
        init(isSelected:Bool) {
            self.isSelected = isSelected
        }
    }
    
    struct SelectionView: View {
    
        var objs: [dummyObject] = [dummyObject.init(isSelected: false)]
    
        var body: some View {
            HStack{
                ForEach(objs) { obj in
                    ObjectButton(obj: obj)
                }
            }
        }
    }
    
    struct ObjectButton: View {
    
        @ObservedObject var obj: dummyObject
    
        var body: some View {
            Button(action: {
                self.obj.isSelected.toggle()
                print("\(self.obj.isSelected)")
            }) {
    
                VStack {
                    Text("Test")
                        .foregroundColor(obj.isSelected ? Color.white : Color.gray)
                        .font(.caption)
                }
            }.frame(width:55,height: 55)
                .padding()
                .background(obj.isSelected ? Color.red : Color.white)
                .padding(.horizontal, 3)
                .clipShape(Circle()).shadow(radius: 6)
        }
    }
    
    struct SelectionView_Previews: PreviewProvider {
        static var previews: some View {
            SelectionView()
        }
    }
    

    【讨论】:

      【解决方案2】:

      这里修改了您的有效代码快照。使用 Xcode 11.2 / iOS 13.2 测试。

      主要思想是将模型作为值类型,因此对属性的修改会修改模型本身,并且为视图引入@State会在更改时刷新。

      struct dummyObject: Identifiable, Hashable {
          var id = UUID()
          var isSelected: Bool
      }
      
      struct SelectionView: View {
          @State var objs: [dummyObject] = [
              dummyObject(isSelected: false)
          ]
      
          var body: some View {
              HStack{
                  ForEach(Array(objs.enumerated()), id: \.element) { (i, _) in
                      Button(action: {
                          self.objs[i].isSelected.toggle()
                          print("\(self.objs[i].isSelected)")
                      }) {
      
                          VStack {
                              Text("Test")
                                  .foregroundColor(self.objs[i].isSelected ? Color.white : Color.gray)
                                  .font(.caption)
                          }
                      }.frame(width:55,height: 55)
                      .padding()
                          .background(self.objs[i].isSelected ? Color.red : Color.white)
                          .padding(.horizontal, 3)
                      .clipShape(Circle()).shadow(radius: 6)
                  }
              }.frame(minWidth: 0, maxWidth: .infinity)
              .padding()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-14
        • 2014-07-22
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        • 2021-11-27
        • 2022-11-22
        • 1970-01-01
        相关资源
        最近更新 更多