【发布时间】:2022-08-23 20:54:19
【问题描述】:
我想使用List、@FocusState 跟踪焦点,并使用.onChanged(of: focus) 确保当前焦点字段在ScrollViewReader 中可见。问题是:当所有东西都设置在一起时,List 在滚动过程中不断重建,使得滚动不像它需要的那样平滑。
当我附加.onChanged(of: focus) 时,我发现List 在滚动时会重建。如果我用ScrollView 替换List,问题就消失了,但我喜欢List 的外观,我需要部分支持,我需要编辑功能(例如删除、移动项目),所以我需要坚持@987654331 @ 看法。
我使用Self._printChanges() 来查看是什么让身体在滚动时重建自身,输出如下:
ContentView: _focus changed.
ContentView: _focus changed.
ContentView: _focus changed.
ContentView: _focus changed.
...
附在.onChanged(of: focus) 的封盖上没有打印任何内容。下面是一个简化的例子,在这个例子中滚动的平滑度不是问题,但是,一旦列表内容或多或少复杂,平滑滚动就会消失,这真的是由于.onChanged(of: focus) :(
问题:是否有机会监听焦点变化并且不会引发列表在滚动时重建自身?
struct ContentView: View {
enum Field: Hashable {
case fieldId(Int)
}
@FocusState var focus: Field?
@State var text: String = \"\"
var body: some View {
List {
let _ = Self._printChanges()
ForEach(0..<100) {
TextField(\"Enter the text for \\($0)\", text: $text)
.id(Field.fieldId($0))
.focused($focus, equals: .fieldId($0))
}
}
.onChange(of: focus) { _ in
print(\"Not printed unless focused manually\")
}
}
}
-
我没有观察到 Xcode 13.4 / iOS 15.5 的描述行为。滚动时没有输出,在任何文本字段中点击一个“ContentView:_focus changed”和一个“Not print unless手动聚焦”按预期打印。
-
@Asperi 这个想法是不要关注任何领域,请滚动列表。让我知道您是否仍然在滚动时看不到“ContentView: _focus changed.\”。一旦一个字段获得焦点,滚动就真的没有输出了。 (Xcode 13.4.1 /iOS 15.5)
-
是的,有趣的效果......不能说它是否是一个错误。
-
我注意到带有 LazyVStack 的 ScrollView 提供与 List 相同的效果,因此这与视图的动态特性有关:行是动态创建的,而 .focused 修饰符 \"changes\" 焦点 var 反过来又是由于存在of .onChange(of: focus) 触发重建...这是我的理论:) 但是如何解决呢?我正在考虑仅在未滚动 List 时附加 .onChange(of:focus) ,但我不知道该怎么做。
标签: swiftui