视图行不反映正确的值

huangapple go评论58阅读模式
英文:

View row does not reflect correct value

问题

以下是您要翻译的内容:

"I am trying to display a list of items, each item having an index and a visibility flag. When I change the visibility of the item, and then move it down the list, the visibility of the item is not correctly reflected in the list.

To reproduce the issue 1) add 3 items by tapping on the + button, 2) change visibility of PLOT 1 by tapping on the eye icon, 3) tap the down icon on PLOT 1 swapping it with PLOT 2. I am expecting that PLOT 1 will have visibility false and PLOT 2 will have visibility true, but instead they are reversed: PLOT 2 has visibility false, and PLOT 1 has visibility true, which is incorrect.

视图行不反映正确的值

视图行不反映正确的值

视图行不反映正确的值

This code is running in macOS 13.0 app in Xcode 14.2 Swift 5"

以上内容已被翻译。

英文:

I am trying to display a list of items, each item having an index and a visibility flag. When I change the visibility of the item, and then move it down the list, the visibility of the item is not correctly reflected in the list.

To reproduce the issue 1) add 3 items by tapping on the + button, 2) change visibility of PLOT 1 by tapping on the eye icon, 3) tap the down icon on PLOT 1 swapping it with PLOT 2. I am expecting that PLOT 1 will have visibility false and PLOT 2 will have visibility true, but instead they are reversed: PLOT 2 has visibility false, and PLOT 1 has visibility true, which is incorrect.

视图行不反映正确的值

视图行不反映正确的值

视图行不反映正确的值

This code is running in macOS 13.0 app in Xcode 14.2 Swift 5

import SwiftUI

struct ContentView: View {
    
    class Plot : Equatable {
        static func == (lhs: ContentView.Plot, rhs: ContentView.Plot) -> Bool {
            lhs === rhs
        }
        
        internal init(index: Int, visible: Bool = true) {
            self.index = index
            self.visible = visible
        }
        
        let index : Int
        var visible : Bool = true
    }
    
    struct PlotView : View {
        
        let plot : Plot
        
        struct Delegate {
            let moveDown : ()->Void
            let canMoveDown : ()->Bool
        }
        
        let delegate : Delegate
        
        @State private var visible = false
        
        var body : some View {
            HStack {
                Text("PLOT \(plot.index)")
                
                Button(action: {
                    visible.toggle()
                }, label: {
                    Image(systemName: "eye.circle" + (visible ? ".fill" : ""))
                })
                
                Button(action: {
                    delegate.moveDown()
                }, label: {
                    Image(systemName: "chevron.down.circle")
                })
                .disabled(!delegate.canMoveDown())
            }
            .onAppear {
                visible = plot.visible
            }
            .onChange(of: visible) { v in
                plot.visible = v
                print("changed plot[\(plot.index)].visible = \(plot.visible ? "true" : "false")")
            }
        }
    }
    
    @State private var plots : [Plot] = []
    
    var body: some View {
        VStack {
            
            ForEach(0..<plots.count, id: \.self) { i in
                PlotView.init(plot: plots[i], delegate: .init(moveDown: {
                    if i < plots.count-1 {
                        plots.swapAt(i, i+1)
                    } else {
                        plots.insert(plots.removeLast(), at: 0)
                    }
                }, canMoveDown: {
                    !plots.isEmpty
                }))
            }

            Button(action: {
                plots.append(.init(index: plots.count))
            }, label: {
                Image(systemName: "plus.circle")
            })
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

答案1

得分: 1

I cannot say exactly why it doesn't work but it works with a Plot struct and @Binding

Don't nest the things, it's bad practice.

This is Plot, it became pretty tiny

struct Plot : Equatable, Identifiable {
    let id = UUID()
    let index : Int
    var visible : Bool = true
}

Edit: In ContentView the ForEach expression iterates the element rather than the indices

struct ContentView: View {
    @State private var plots : [Plot] = []
        
    var body: some View {
        VStack {
            ForEach($plots) { $plot  in
                PlotView.init(plot: $plot, delegate: .init(moveDown: {
                    if let i = plots.firstIndex(of: plot),
                       i < plots.count-1 {
                        plots.swapAt(i, i+1)
                    } else {
                        plots.insert(plots.removeLast(), at: 0)
                    }
                }, canMoveDown: {
                    !plots.isEmpty
                }))
            }
            
            Button(action: {
                plots.append(.init(index: plots.count))
            }, label: {
                Image(systemName: "plus.circle")
            })
        }
    }
}

In Plotview the Plot instance is bound and the extra visible property as well as the .onChange modifier are not needed.

struct PlotView : View {
    @Binding var plot : Plot
    
    struct Delegate {
        let moveDown : ()->Void
        let canMoveDown : ()->Bool
    }
    
    let delegate : Delegate
    
    var body : some View {
        HStack {
            Text("PLOT \(plot.index)")
            
            Button(action: {
                plot.visible.toggle()
            }, label: {
                Image(systemName: "eye.circle" + (plot.visible ? ".fill" : ""))
            })
            
            Button(action: {
                delegate.moveDown()
            }, label: {
                Image(systemName: "chevron.down.circle")
            })
            .disabled(!delegate.canMoveDown())
        }
    }
}
英文:

I cannot say exactly why it doesn't work but it works with a Plot struct and @Binding

Don't nest the things, it's bad practice.

This is Plot, it became pretty tiny

struct Plot : Equatable, Identifiable {
    let id = UUID()
    let index : Int
    var visible : Bool = true
}

Edit: In ContentView the ForEach expression iterates the element rather than the indices

struct ContentView: View {
    
    @State private var plots : [Plot] = []
        
        var body: some View {
            VStack {
                ForEach($plots) { $plot  in
                    PlotView.init(plot: $plot, delegate: .init(moveDown: {
                        if let i = plots.firstIndex(of: plot),
                           i &lt; plots.count-1 {
                            plots.swapAt(i, i+1)
                        } else {
                            plots.insert(plots.removeLast(), at: 0)
                        }
                    }, canMoveDown: {
                        !plots.isEmpty
                    }))
                }
                
                Button(action: {
                    plots.append(.init(index: plots.count))
                }, label: {
                    Image(systemName: &quot;plus.circle&quot;)
                })
            }
        }
    }
}

In Plotview the Plot instance is bound and the extra visible property as well as the .onChange modifier are not needed.

struct PlotView : View {
      
      @Binding var plot : Plot
      
      struct Delegate {
          let moveDown : ()-&gt;Void
          let canMoveDown : ()-&gt;Bool
      }
      
      let delegate : Delegate
      
      var body : some View {
          HStack {
              Text(&quot;PLOT \(plot.index)&quot;)
              
              Button(action: {
                  plot.visible.toggle()
              }, label: {
                  Image(systemName: &quot;eye.circle&quot; + (plot.visible ? &quot;.fill&quot; : &quot;&quot;))
              })
              
              Button(action: {
                  delegate.moveDown()
              }, label: {
                  Image(systemName: &quot;chevron.down.circle&quot;)
              })
              .disabled(!delegate.canMoveDown())
          }
      }
  }

huangapple
  • 本文由 发表于 2023年2月23日 21:46:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545677.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定