SwiftUI长按带LongPressGesture的Shift按钮时条件渲染Button首次点击失效
修复后完整代码
struct ContentView: View { @State private var isShifted = false var body: some View { VStack { Spacer() // 合并A/B按钮为同一视图,避免切换时视图身份重置 Button(action: { if isShifted { print("B tapped! (shifted!)") } else { print("A tapped (non-shifted)") } }, label: { Image(systemName: isShifted ? "b.square.fill" : "a.circle.fill") .imageScale(.large) }) Spacer() // 重写Shift按钮的手势逻辑 Image(systemName: "shift.fill") .imageScale(.large) .gesture( // 用DragGesture统一处理按下和抬起事件,minimumDistance设为0保证按下立刻触发 DragGesture(minimumDistance: 0) .onChanged { _ in isShifted = true } .onEnded { _ in isShifted = false } ) Spacer() Button(action: { print("C tapped") }, label: { Image(systemName: "c.square") .imageScale(.large) }) Spacer() } // 开启多触控支持,允许按住Shift的同时响应其他按钮的点击 .allowsMultipleTouches(true) } }
修复说明
- 合并A/B两个独立按钮为同一个视图,仅根据
isShifted状态切换图标和点击逻辑,避免了if/else切换视图时视图身份重置导致的原有触控序列丢失问题,单指按住Shift后点击该按钮即可响应,无需再使用第二根手指操作。 - 替换Shift按钮原有
LongPressGesture + 原生Button action的组合实现,改用minimumDistance = 0的DragGesture统一处理按下和抬起逻辑,规避了两种手势的优先级冲突,状态切换更灵敏可靠。 - 给根容器添加
allowsMultipleTouches(true)配置,显式开启多触控支持,保证按住Shift按钮的同时,其他按钮的点击事件可以正常被识别。 - 保留C按钮原有逻辑,全程不受Shift状态影响,符合需求。
内容的提问来源于stack exchange,提问作者Joseph Dvorak
相关产品推荐
相关产品推荐

