SwiftUI中offset后置gesture导致CPU满载、UI无响应问题排查
为什么SwiftUI中offset修饰符位置错误会导致拖拽无限循环?
问题核心原因
你的问题出在SwiftUI修饰符的顺序和手势的坐标基准逻辑上:
当把
offset放在gesture之后时:
每次在onChanged里修改currentPosition,offset会立刻改变View的显示位置。但DragGesture的value.translation是基于View的当前渲染位置计算的——View位置一变,手势的坐标基准也跟着变了,这会让手势再次检测到"新的拖拽偏移",重新触发onChanged,再次修改currentPosition,进而再次更新offset。
这种连锁反应形成了无限循环,所以控制台会反复打印"DragEffectViewModifier-ondrag",CPU被持续占用导致满载,UI直接失去响应。当把
offset放在gesture之前时:gesture绑定在offset调整前的View"原始布局位置"上,拖拽的translation基准点固定在View的初始位置,不会因为offset改变而变化。此时修改currentPosition只会改变View的显示位置,不会影响手势的偏移计算,自然不会触发循环。
修正后的代码
把offset移到gesture前面即可解决问题:
struct ContentView: View { @State private var currentPosition: CGSize = .zero @State private var newPosition: CGSize = .zero var body: some View { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) .offset(x: currentPosition.width, y: currentPosition.height) // 移到gesture前面 .gesture(DragGesture() .onChanged { value in print("DragEffectViewModifier-ondrag") currentPosition = CGSize(width: 0, height: value.translation.height + newPosition.height) } .onEnded { value in newPosition = currentPosition }) } }
内容的提问来源于stack exchange,提问作者test1229
相关产品推荐
相关产品推荐

