iOS 14 SwiftUI 键盘自动提升视图
Posted
技术标签:
【中文标题】iOS 14 SwiftUI 键盘自动提升视图【英文标题】:iOS 14 SwiftUI Keyboard lifts view automatically 【发布时间】:2021-01-05 13:54:19 【问题描述】:我在视图中使用 TextField,当它成为第一响应者时,它会离开视图,如下 GIF 所示。
有什么办法可以摆脱这种行为吗?
这是我的代码
NavigationView(content:
ZStack
MyTabView(selectedIndex: self.$index)
.view(item: self.item1)
NewView(title: "Hello1").navigationBarTitle("")
.navigationBarHidden(true)
.view(item: self.item2)
NewView(title: "Hello2").navigationBarTitle("")
.navigationBarHidden(true)
.view(item: self.item3)
NewView(title: "Hello3").navigationBarTitle("")
.navigationBarHidden(true)
.navigationBarHidden(true)
.navigationBarTitle("")
).ignoresSafeArea(.keyboard, edges: .bottom)
// 新视图
struct NewView:View
@State var text:String = ""
var title:String
var body: some View
VStack
Spacer()
Text("Hello")
TextField(title, text: self.$text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
.onAppear
debugPrint("OnApper \(self.title)")
【问题讨论】:
为什么要摆脱这种行为?如果您不抬起文本字段,它会被键盘覆盖并且您无法分辨您正在输入的内容,或者使用点击/拖动手势来更改选择。它使编辑无法使用。 因为在 ios13 中,键盘只是简单地自动切换......正如预期的那样。我们不得不再次为 ios14 添加 if 语句。而且我相信 ios15 还会有更多的 if 语句。 【参考方案1】:要使.ignoresSafeArea
工作,您需要填充所有可用区域(例如,使用Spacer
)。
以下不起作用(没有 Spacers,只是一个 TextField):
struct ContentView: View
@State var text: String = ""
var body: some View
VStack
TextField("asd", text: self.$text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.ignoresSafeArea(.keyboard, edges: .bottom)
但是,当您添加 Spacers(填充所有可用空间)时,它会起作用:
struct ContentView: View
@State var text: String = ""
var body: some View
VStack
Spacer()
TextField("asd", text: self.$text)
.textFieldStyle(RoundedBorderTextFieldStyle())
Spacer()
.ignoresSafeArea(.keyboard, edges: .bottom)
如果您不想使用 Spacers,也可以使用 GeometryReader
:
struct ContentView: View
@State var text: String = ""
var body: some View
GeometryReader _ in
...
.ignoresSafeArea(.keyboard, edges: .bottom)
【讨论】:
如果你有这个修改器,所有它都不起作用。 (.edgesIgnoringSafeArea(.all))【参考方案2】:您应该在 ZStack
上应用修饰符,NOT NavigationView
NavigationView(content:
ZStack
,,,
.navigationBarHidden(true)
.navigationBarTitle("")
.ignoresSafeArea(.keyboard, edges: .bottom) // <- This line moved up
)
完整的工作示例:
struct ContentView: View
@State var text = ""
var body: some View
VStack
Spacer()
Text("Hello, World")
TextField("Tap to test keyboard ignoring", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
.ignoresSafeArea(.keyboard, edges: .bottom)
【讨论】:
修饰符根本不起作用。 TextField 仍然向上移动.. :( 可能你错过了原始代码实现。 I. 添加了完整的代码演示,以便您可以重现它;) 如果我在视图中包含一些这样的行:ScrollView LazyVStack Rows ...
使用 ignoresSafeArea
将导致行中的闪烁,这是显而易见且令人讨厌的【参考方案3】:
结合此处发布的答案并考虑this question,最终对我有用的是以下(Xcode 12.4、iOS 14.4):
GeometryReader _ in
VStack
Spacer()
TextField("Type something...", text: $value)
Spacer()
.ignoresSafeArea(.keyboard, edges: .bottom)
两个垫片都用于垂直居中文本字段。
仅使用 GeometryReader 或 ignoresSafeArea
修饰符并不能解决问题,但在如上所示将它们全部放在一起后,最终视图在键盘出现时无法向上移动。
【讨论】:
【参考方案4】:这就是我想出来的:
GeometryReader _ in
ZStack
//PUT CONTENT HERE
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
这似乎对我有用。在这种情况下,您无需检查 iOS 14 的可用性。
【讨论】:
以上是关于iOS 14 SwiftUI 键盘自动提升视图的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI捕获键盘提交动作在iOS15之前和之后的兼容实现