SwiftUI TextField 垂直布局时焦点的问题

水平布局时,滚动正常,回车键也能正常退出编辑。底层是UITextField
垂直布局时,底层是UITextView,表现不一致,出现问题。

  1. 焦点问题需要我们滚动时,锚点设为顶部,proxy.scrollTo($0, anchor: .top)
  2. 回车键,退出编辑失效的问题,需要借助toolbar

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import SwiftUI

struct TestNextTextFieldFocus: View {
@State var inputsValues: [String] = (0..<30).map { i in
"test \(i) TextField axis is \(i % 2 == 0 ? ".vertical" : ".horizontal")"
}

@FocusState var focusedInput: Int?

var body: some View {
ScrollViewReader { proxy in
ScrollView {
LazyVStack {
ForEach(0..<inputsValues.count, id: \.self) { i in
TextField("Value", text: $inputsValues[i], axis: i % 2 == 0 ? .vertical : .horizontal)
.focused($focusedInput, equals: i)
.submitLabel(.return)
.id(i)
.onSubmit {
print("submit \(i)")
// update state here !!
if (i + 1) < inputsValues.count {
focusedInput = i + 1
} else {
focusedInput = nil
}
}
}
}
.onChange(of: focusedInput) {
print("onChange focusedInput:\(String(describing: focusedInput))")
// react on state change here !!
proxy.scrollTo($0, anchor: .top)
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button {
focusedInput = nil
} label: {
Text("Done")
}
}
}
}
}
}

struct TestNextTextFieldFocus_Previews: PreviewProvider {
static var previews: some View {
TestNextTextFieldFocus()
}
}