iOS17+/macOS14+下隐藏步进按钮后自动重复行为未终止问题求助
SwiftUI 步进按钮隐藏后自动重复行为未终止问题
我有一个启用了自动重复功能的步进按钮,嵌套在会根据数值阈值动态隐藏的上层视图中。核心问题:当视图因数值达到阈值被隐藏后,按钮的自动重复行为并未终止。点击「Reset Count」按钮恢复视图显示时,会看到计数持续减少直至再次触发隐藏条件。
该问题仅在iOS 17+和macOS 14+系统中出现,按钮已通过buttonRepeatBehavior(.enabled)开启自动重复,且已向苹果提交反馈(编号FB15477204)。
相关代码示例
步进按钮实现
fileprivate func stepperLabel(isDown: Bool) -> some View { if isDown { Text("-") .font(.title2) .foregroundColor(.primary) .frame(maxWidth: .infinity, minHeight: 40, maxHeight: .infinity, alignment: .leading) .padding(.leading, 16) } else { Text("+") .font(.title2) .foregroundColor(.primary) .frame(maxWidth: .infinity, minHeight: 40, maxHeight: .infinity, alignment: .trailing) .padding(.trailing, 16) } } struct StepperButtonView: View { let isDown: Bool let action: ()->Void var body: some View { Button(action: action) { stepperLabel(isDown: isDown) } .buttonStyle(.plain) .buttonRepeatBehavior(.enabled) } }
上层整合控件
struct StepperNumView<T: Numeric & Comparable>: View { @Binding var value: T let step: T let zeroBased = T.self == UInt.self var body: some View { VStack { HStack(spacing: 0) { StepperButtonView(isDown: true) { if zeroBased { if value == 0 { // 控制台会持续输出该日志,恢复视图后计数会继续减少直至消失 print("skipping adjustment from repeating button") } else { value = max(0, value-step) } } else { value -= step } } .disabled(zeroBased && value == 0) // 省略其余实现代码 } } } }
父视图控制逻辑
struct ContentView: View { @State var count: UInt = 10 var body: some View { VStack { Button("Reset Count") { count = 10 } .buttonStyle(.borderedProminent) Spacer() if count > 0 { Text("Button vanishes when hits zero, holding down on\n+/- to repeat should trigger weird things") Spacer() StepperNumView<Int>(title: "Count, tap centre to edit", value: $count, step: 1) .padding(.horizontal) } else { Text("Button vanished with zero count") } } } }
临时规避方案
由于这是iOS 17+/macOS 14+的系统框架bug,可通过以下方式临时解决:
- 在视图即将隐藏的
onDisappear回调中,手动重置相关状态,或禁用按钮的重复行为 - 在数值达到阈值时,先禁用步进按钮的自动重复,再触发视图隐藏逻辑
内容的提问来源于stack exchange,提问作者Andy Dent
相关产品推荐
相关产品推荐

