在视图中未更新的结构数组

时间:2020-01-08 00:52:48

标签: swift swiftui

我有一个观察对象数组,其中包含一个包含数据的结构数组。我想在屏幕上显示它。该数据最初显示在屏幕上,但是每当我对数组中的项目进行更改时,更改不会被推送。我什至在struct中更改属性。我也在我的经理班上尝试过。我做了一些挖掘工作,多次更改了方法,但是无法正常工作。对于swiftui / swift以及堆栈溢出,我是一个新手。

完整代码:

struct GameView: View {
    @State var value: CGFloat = 0
    @ObservedObject var circles = GameCircles()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var body: some View {
        ZStack {
            Color.primary
                .frame(width: 450, height: 800)
            self.circles.getViews()
                .onReceive(timer) { _ in
                    self.circles.tick()
            }
        }
        .edgesIgnoringSafeArea(.all)
        .gesture(DragGesture(minimumDistance: 20)
        .onChanged { gest in
            self.value = gest.location.x
        })
    }
}
class GameCircles: ObservableObject {
    @Published var circles: [GameCircle] = []

    func getViews() -> some View {
        ForEach(circles, id: \.id) { circle in
            circle.makeView()
        }
    }

    func tick() {
        for circle in circles {
            circle.tick()
            print(circle.y)
        }
        circles.append(GameCircle(x: Int.random(in: -200...200), y: -200))
    }

}

struct GameCircle: Identifiable {
    @State var x: Int
    @State var y: Int
    let color = Color.random()
    var id = UUID()

    func tick() {
        self.y += 1
    }

    func makeView() -> some View {
        return ZStack {
            Circle()
                .frame(width: 40, height: 40)
                .foregroundColor(color)
                .animation(.default)
            Text("\(Int(y))")
                .foregroundColor(.black)
        }
        .offset(x: CGFloat(self.x), y: CGFloat(self.y))
    }
}

1 个答案:

答案 0 :(得分:0)

我一直在玩这段代码,试图解决您的问题。令我惊讶的是,export default class App extends React.Component { render() { return <AppContainer />; } } 中的state varView循环中没有改变(您将在屏幕截图中看到它)。好的,我重写了您的代码,现在圈了下来:

ForEach

enter image description here

您可以看到// MARK: models class GameCircles: ObservableObject { @Published var circles: [CircleModel] = [] func addNewCircle() { circles.append(CircleModel(x: CGFloat.random(in: -200...200), y: -200)) } } struct CircleModel: Identifiable, Equatable { let id = UUID() var x: CGFloat var y: CGFloat mutating func pushDown() { self.y += 5 } } // MARK: views struct GameView: View { @State var gameSeconds = 0 @ObservedObject var game = GameCircles() let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() var body: some View { ZStack { Color.primary .frame(width: 450, height: 800) ForEach(self.game.circles) { circle in CircleView(y: circle.y) .offset(x: circle.x, y: circle.y) .onReceive(self.timer) { _ in let circleIndex = self.game.circles.firstIndex(of: circle)! self.game.circles[circleIndex].pushDown() } } .onReceive(self.timer) { _ in self.game.addNewCircle() } } .edgesIgnoringSafeArea(.all) } } struct CircleView: View { @State var y: CGFloat var body: some View { ZStack { Circle() .frame(width: 40, height: 40) .foregroundColor(.red) .animation(.default) Text("\(Int(y))") .foregroundColor(.black) } } } struct GameView_Previews: PreviewProvider { static var previews: some View { GameView() } } 没有变化,我想知道为什么吗?不过,我希望它能对您有所帮助。

PS 我重写了几次代码,所以这不是唯一的解决方案,您可以像问题中一样使用@State var y func,代码会更加清晰

tick()