【问题标题】:How to pass reference to underlying array struct to a view?如何将对底层数组结构的引用传递给视图?
【发布时间】:2021-03-21 00:43:12
【问题描述】:

在下面的示例中,我想修改数组中的结构,该数组用于从该视图生成视图。它会导致一个明显的错误(在 ForEach 中,对当前处理项目的引用是一个 let 常量)。在运行时与视图交互时,我还能如何修改原始数组行?换句话说,我如何存储/传递对相应数组项的引用?

我还尝试将数组索引传递到视图内部并通过array[index].someproperty 直接访问它。它工作得很好......直到我尝试删除行。在这种情况下,动态视图不再包含正确的索引,通常会导致超出范围的错误。

在下面的示例中,我想将拖动位置保存到原始数组而不是视图本身,以便以后可以对其执行逻辑(不能遍历视图,但可以轻松地遍历它们的底层数组)。有人可以指出正确的方法吗?谢谢!

编辑:澄清:这里的目标是让拖动手势将值写入 ballStorage 对象的数组并生成相应的视图。但它需要知道要修改哪一行!

import SwiftUI


let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height


struct SingleBall: Identifiable {
    var id = UUID()
    var position = CGPoint.zero
}

class BallStorage: ObservableObject {
    
    @Published var balls: [SingleBall] = [
        
        SingleBall(position: CGPoint(x: 110, y: 220)),
        SingleBall(position: CGPoint(x: 150, y: 120)),
        SingleBall(position: CGPoint(x: 200, y:160)),
        SingleBall(position: CGPoint(x: 200, y: 200))
        
    ]
    
}


struct StartScreen: View {
    
    
    @StateObject var ballStorage = BallStorage()
    
    
    var body: some View {
        
        
        
        ZStack { // stack of balls
            
            
            ForEach(ballStorage.balls, id: \.id) {
                
                ball in
                littleBall(id: ball.id).position(ball.position).gesture(DragGesture()
                                                                            
                .onChanged {
                gesture in
 ball.position = gesture.location //ERROR! can't modify ball (it's a let constant)
                                                                            }
                                                                        
                )
                
            }
            
        }.frame(width:screenWidth, height:screenHeight) //end stack balls
        
        
    }
    
}

struct test_Previews: PreviewProvider {
    static var previews: some View {
        
        StartScreen()
        
    }
}

编辑:我尝试的另一件事是将“球”(参见代码)传递到视图内部。我可以在那里修改它,视图会对更改做出反应,但在这种情况下,传递的是数组项的副本,而不是对原始数组中实际结构的引用。所以修改数组对视图没有影响。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    您需要修改原始数组,因此您需要一个索引,您可以通过在索引上执行 ForEach 来获得:

    ForEach(ballStorage.balls.indices, id: \.self) { index in
       littleBall(id: ballStorage.balls[index].id)
          .position(ballStorage.balls[index].position)
          //...
          .onChanged { gesture in
              // modify ballStorage.balls[index]
              ballStorage.balls[index].position = gesture.location
          }
    }
    

    【讨论】:

    • 谢谢!所以这很好用,直到我从数组中删除一行(我需要能够这样做)。在这种情况下,它将导致超出范围错误和崩溃。
    • 所以,that 是一个不同的问题,类似于:stackoverflow.com/q/63079221/968155
    • 我很害怕——我讨厌使用奇怪的 hacky 扩展来解决一些超级基本的问题。我宁愿等待苹果解决这个问题。无论如何,它看起来确实是使用索引访问原始数组的最佳方法,这是原始问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多