SwiftUI List底部不可见的TextEditor调用.focused修饰符不生效问题

问题原因
SwiftUI的List基于UITableView的Cell复用机制实现,只有处于可视区域内的元素才会被加载到渲染树中。当TextEditor滚动到不可见区域时,对应的视图实例会被回收,此时直接修改focused状态无法作用到不存在的视图上,自然无法触发聚焦和键盘唤起。
解决方案
实现核心逻辑为先滚动到TextEditor所在位置,等视图加载完成后再激活聚焦,借助ScrollViewReader实现滚动定位即可,全版本兼容的修正代码如下:
import SwiftUI struct ContentView: View { var array = Array(0...20) @State private var newItemText : String = "" @FocusState var focused: Bool var body: some View { VStack{ ScrollViewReader { proxy in List{ ForEach(array, id: \.self) { Text("\($0)") } TextEditor(text: $newItemText) .focused($focused) .id("textEditor") // 给TextEditor设置唯一标识用于定位 } Button { // 先滚动到TextEditor的位置 withAnimation { proxy.scrollTo("textEditor", anchor: .bottom) } // 等待滚动动画完成后激活焦点,0.3秒为系统默认滚动动画时长 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { focused = true } } label: { Text("Add Item") } } } } }
如果目标版本为iOS 17及以上,可以使用系统提供的滚动完成回调替代硬编码延迟,逻辑更精准:
// 仅替换Button的action部分即可 Button { proxy.scrollTo("textEditor", anchor: .bottom) { _ in // 滚动完成直接激活焦点 focused = true } } label: { Text("Add Item") }
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

