swiftui-ui-patterns - focus
焦点处理与字段串联意图使用FocusState控制键盘焦点、串联字段并在复杂表单中协调焦点。核心模式使用枚举表示可聚焦的字段。在onAppear中设置初始焦点。使用.onSubmit将焦点移动到下一个字段。对于动态字段列表使用带关联值的枚举例如.option(Int)。示例单字段焦点structAddServerView:View{StateprivatevarserverFocusStateprivatevarisServerFieldFocused:Boolvarbody:someView{Form{TextField(Server,text:$server).focused($isServerFieldFocused)}.onAppear{isServerFieldFocusedtrue}}}示例用枚举串联焦点structEditTagView:View{enumFocusField{casetitle,symbol,newTag}FocusStateprivatevarfocusedField:FocusField?varbody:someView{Form{TextField(Title,text:$title).focused($focusedField,equals:.title).onSubmit{focusedField.symbol}TextField(Symbol,text:$symbol).focused($focusedField,equals:.symbol).onSubmit{focusedField.newTag}}.onAppear{focusedField.title}}}示例可变字段的动态焦点structPollView:View{enumFocusField:Hashable{caseoption(Int)}FocusStateprivatevarfocused:FocusField?Stateprivatevaroptions:[String][,]StateprivatevarcurrentIndex0varbody:someView{ForEach(options.indices,id:\.self){indexinTextField(Option\(index1),text:$options[index]).focused($focused,equals:.option(index)).onSubmit{addOption(at:index)}}.onAppear{focused.option(0)}}privatefuncaddOption(at index:Int){options.append()currentIndexindex1DispatchQueue.main.asyncAfter(deadline:.now()0.01){focused.option(currentIndex)}}}应保留的设计选择让焦点状态保持在拥有字段的视图本地。用焦点变化驱动 UX验证消息、辅助 UI。使用 ScrollView/Form 时配合.scrollDismissesKeyboard(...)。陷阱不要把焦点状态存储在共享对象中它是视图局部的。避免在动画期间激进地切换焦点如有必要可延迟。