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

SwiftUI问题:变量更新后绘制光伏板的Path未自动重绘

问题解决:SwiftUI中Shape未随ObservedObject更新而刷新

问题根源

drawPanels是值类型的Shape,你在其中使用@ObservedObject监听variables变化,但值类型内的@ObservedObject无法触发SwiftUI重新调用path(in:)方法。尽管variables数值已更新,且path方法能打印出新值,但SwiftUI未检测到Shape实例的变化,因此不会重新绘制路径。

解决方法

方法1:为Shape添加标识ID

在displayPanelSpacing视图中,给drawPanels绑定.id()修饰符,关联到variables.tiltAngle:

drawPanels(variables: variables)
    .id(variables.tiltAngle) // 角度变化时强制重建Shape实例
    .stroke(changeLine ? Color(.red) : .gray, lineWidth: 3.0)
    .frame(width: (GlobalVariables.screenWidth - 64), height: 150)
    .padding(.leading, 16)
    .padding(.trailing, 16)
    .scaleEffect(changeLine ? 0.5 : 1.0)
    .overlay(DrawSun(radius: 25).foregroundColor(.orange))

当tiltAngle更新时,SwiftUI会判定这是新的drawPanels实例,从而重新执行path(in:)生成新路径。

方法2:让Shape遵循Equatable

若Variables类实现了Equatable,可让drawPanels也遵循该协议,SwiftUI会自动检测属性变化并刷新:

struct drawPanels: Shape, Equatable {
    static func == (lhs: drawPanels, rhs: drawPanels) -> Bool {
        // 比较影响路径生成的核心属性,这里用倾斜角度即可
        return lhs.variables.tiltAngle == rhs.variables.tiltAngle
    }

    let variables: Variables // 改为普通let属性,无需@ObservedObject

    func path(in rect: CGRect) -> Path {
        // 原有路径生成代码保持不变
        let result = variables.ed()
        let edEndX = result.endX
        let edEndY = result.endY

        let baselineY = rect.maxY
        let baselineXOffset = 10
        let panelY = Int(rect.maxY) - edEndY
        let panel1X = baselineXOffset + edEndX
        let panel2X = baselineXOffset + Int(rect.midX) + edEndX
        
        var path = Path()
        path.move(to: CGPoint(x: rect.minX + 10, y: baselineY))
        path.addLine(to: CGPoint(x: panel1X, y: panelY))
        path.move(to: CGPoint(x: rect.midX + 10, y: baselineY))
        path.addLine(to: CGPoint(x: panel2X, y: panelY))
        return path
    }
}

修改后,SwiftUI会自动对比前后drawPanels实例的属性,当variables.tiltAngle变化时重新计算路径。

额外编码规范建议

  • Swift中结构体/视图命名应遵循大驼峰式,建议把drawPanels改为DrawPanels,displayPanelSpacing改为DisplayPanelSpacing。
  • 调试用的打印语句建议在调试完成后移除,避免不必要的性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:13:09