SwiftUI:实现点击按钮启用Apple Watch数码表冠输入,解决需点击两次按钮的问题
解决Apple Watch数码表冠需两次点击启用的问题
我帮你排查出了问题所在,也整理好了修改方案,咱们来看具体怎么调整:
问题根源
你当前的代码里,第一次点击“Enable Crown”时,虽然将forceFocus设为true并调用了resetFocus,但resetFocus只是重置焦点范围,并没有主动把焦点分配给目标按钮。prefersDefaultFocus更多是在初始加载或焦点范围重置后自动选择默认焦点,但这里状态变化和重置操作的时机没配合好,导致第一次点击后焦点没正确落在可捕获表冠事件的按钮上,所以需要第二次点击才能生效。
修改后的完整代码
struct ContentView: View { @State var crownValue = 0.0 @Namespace private var namespace @FocusState private var isButtonFocused: Bool // 替换原来的forceFocus var body: some View { ScrollView { VStack { Button("Button") { } .focusable() // 这里不需要再传forceFocus参数 .focused($isButtonFocused) // 绑定焦点状态变量 .prefersDefaultFocus(true, in: namespace) Text("\(crownValue)") } .digitalCrownRotation($crownValue) Button("Enable Crown") { print("Enabling crown") isButtonFocused = true // 直接设置焦点到目标按钮 } } .focusScope(namespace) } }
关键改动说明
- 用
@FocusState控制焦点:@FocusState是SwiftUI专门用来管理焦点状态的属性包装器,比手动切换focusable的参数更精准可靠,能直接控制某个视图是否获得焦点。 - 绑定焦点状态到目标按钮:通过
.focused($isButtonFocused)修饰符,把按钮的焦点状态和变量绑定,当变量设为true时,按钮会立即获得焦点。 - 简化点击事件逻辑:不需要再调用
resetFocus,直接设置isButtonFocused = true就能让目标按钮获取焦点,数码表冠的旋转事件会立刻被digitalCrownRotation($crownValue)捕获。
这样修改后,点击一次“Enable Crown”按钮就能立即启用数码表冠的输入功能啦。
内容的提问来源于stack exchange,提问作者t9mike




