You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI视图无缩放手势时不更新问题求助

问题分析

你的核心问题是Player类作为ObservableObject,属性变更时没有触发视图更新。只有当缩放操作修改了@State标记的scale变量时,ContentView才会强制重绘,从而显示更新后的内容。

原因是ObservableObject需要通过@Published标记要监听的属性,或者手动发送变更通知,否则SwiftUI无法感知属性值的变化。你的Player类里的_actualPoint和_movePoints没有任何发布标记,所以修改它们的值不会触发视图刷新。

解决方案

方法1:用@Published自动发布属性变更

直接在Player类的私有属性前添加@Published修饰符,属性值改变时会自动通知视图更新:

import SwiftUI

class Player: ObservableObject {
    
    private var _speedX: Double = 0.0
    private var _speedY: Double = 1.0
    @Published var _actualPoint: Array<Double>
    @Published var _movePoints: Array<Array<Double>>
    private var _color: SwiftUI.Color
    
    // 其余初始化、属性代码保持不变
}

方法2:手动发送变更通知(适合自定义逻辑场景)

如果不想用@Published,可以在属性的setter里手动调用objectWillChange.send(),主动通知SwiftUI属性即将变更:

public var actualPoint: Array<Double> {
    get{
        return self._actualPoint
    }
    set{
        objectWillChange.send()
        self._actualPoint = newValue
    }
}

public var movePoints: Array<Array<Double>> {
    get{
        return self._movePoints
    }
    set{
        objectWillChange.send()
        self._movePoints = newValue
    }
}

额外优化:修复ContentView的ForEach逻辑

你的ContentView中ForEach存在逻辑冗余:

  • ForEach(player1.actualPoint, id:\.self)遍历的是actualPoint里的每个Double值,但每次都创建同一个DrawNextPoints视图,会导致重复绘制。
  • 同理ForEach(player1.movePoints, id:\.self)也存在相同问题。

建议修改为传递具体的点数据给子视图:

ForEach(player1.movePoints, id:\.self) { point in
    DrawPlayer(point: point, color: player1.color)
}

(需要同步修改DrawPlayer的初始化参数,接收具体的坐标点和颜色,而非整个Player对象)

验证修改

完成上述修改后,点击DrawNextPoints的圆形时,Player的属性变更会立即通知ContentView更新,无需再通过缩放操作触发重绘。

内容的提问来源于stack exchange,提问作者ElCarmino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:32:44