@ObservedObject更改后,SwiftUI视图未更新

时间:2020-07-02 10:53:08

标签: ios swift swiftui state observedobject

预期功能:

  1. 点击以添加圈子
  2. 按“下一步”创建新的“框架”
  3. 将圈子拖到新位置
  4. 按“后退”可将圆恢复到先前的位置

问题: 如上图所示,当我点击“后退”的最后一部分时,圆圈停留在拖动位置,而不是按预期方式还原。

例如当我将圆添加到(0,0)时,创建一个新框架,将该圆拖到新位置(10,10),然后点击“返回”,控制台将打印“ 框架:0,位置(0, 0)”。然后,当我点击下一步时,它会显示“ 帧:1,位置(10,10)”。然后点击“返回”将再次打印(0,0)。但是“圈子”位置不会更新。

我尝试为DraggableCircleModel结构使用一个类,并在其位置上使用@Published,但这似乎效果不佳。

我在下面提供了我的课程,以提供更多背景信息。另外,这只是我第二次在此处发布问题,因此,对改善我的问题的任何建议将不胜感激。谢谢你!

后退和下一步按钮

Button(action: {
    self.viewModel.goTo(arrangementIndex: self.viewModel.currentIndex - 1)
}) { Text("Back") }

Button(action: {
    self.viewModel.goTo(arrangementIndex: self.viewModel.currentIndex + 1)
}) { Text("Next")}

用于显示圈子的视图:

struct DisplayView: View {

@ObservedObject var viewModel: ViewModel

var body: some View {
    ZStack {
        Rectangle()
            .overlay(
                TappableView { location in
                    self.viewModel.addCircle(at: location)
            })
        ForEach(self.viewModel.currentArrangement.circles, id: \.id) { circle in
            return DraggableCircleView(viewModel: self.viewModel,
                       circleIndex: circle.circleIndex,
                       diameter: 50,
                       offset: circle.position)
        }
    }
}

}

DraggableCircle视图的相关部分

struct DraggableCircleView: View {
    init(viewModel: ViewModel, circleIndex: Int, diameter: CGFloat, offset: CGPoint) {
        // Initialize
        ...
        _viewState = /*State<CGSize>*/.init(initialValue: CGSize(width: offset.x, height: offset.y))

        // **Debugging print statement**
        print("\(self.viewModel.currentCircles.forEach{ print("Frame: \(self.viewModel.currentIndex), position \($0.position)") }) \n")
    }

    var body: some View {
    let minimumLongPressDuration = 0.0
    let longPressDrag = LongPressGesture(minimumDuration: minimumLongPressDuration)
        .sequenced(before: DragGesture())
        .updating($dragState) { value, state, transaction in
            // Update circle position during drag
            ...
        }
        .onEnded { value in
            guard case .second(true, let drag?) = value else { return }
            // get updated position of circle after drag
            ...
            self.viewModel.setPositionOfCircle(at: self.circleIndex, to: circlePosition)
        }
    
    return Circle()
        // Styling omitted
        ...
        .position(
            x: viewState.width + dragState.translation.width,
            y: viewState.height + dragState.translation.height
        )
        .gesture(longPressDrag)

}

1 个答案:

答案 0 :(得分:0)

解决了。问题在于DraggableCircle视图的.position(...)修饰符。以前,它仅反映DraggableCircle的状态,而不是根据基础ViewModel和Model进行更新。

将其更改为:

.position(
    x: self.viewModel.currentCircles[circleIndex].position.x + dragState.translation.width,
    y: self.viewModel.currentCircles[circleIndex].position.y + dragState.translation.height)

成功了。这是因为DraggableCircle的位置现在反映了基础ViewModel而不是DraggableCircle的状态。