iOS 14 SwiftUI 键盘自动提升视图

Mal*_*oni 12 keyboard textfield swift swiftui ios14

我在我的视图中使用 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)
Run Code Online (Sandbox Code Playgroud)

// 新视图

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)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

paw*_*222 15

为了.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)
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当您添加 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想使用 Spacers,您还可以使用GeometryReader

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        GeometryReader { _ in
            ...
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你有这个修改器,一切都不起作用。(.edgesIgnoringSafeArea(.all)) (3认同)

Moj*_*ini 10

您应该应用的修改上ZStack不是NavigationView

NavigationView(content: {
    ZStack{
        ,,,
    }.navigationBarHidden(true)
    .navigationBarTitle("")
    .ignoresSafeArea(.keyboard, edges: .bottom) // <- This line moved up
})
Run Code Online (Sandbox Code Playgroud)

完整的工作示例:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

演示

  • 修改器根本不起作用。TextField 仍然向上移动..:( (6认同)

edf*_*ria 6

这就是我想出来的:

GeometryReader { _ in
    ZStack {
        //PUT CONTENT HERE
    }.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
Run Code Online (Sandbox Code Playgroud)

这似乎对我有用。在这种情况下,您不需要检查 iOS 14 的可用性。


Gab*_*abb 5

最终对我有用的,结合这里发布的答案并考虑这个问题,如下(Xcode 12.4,iOS 14.4):

GeometryReader { _ in
    VStack {
        Spacer()
        TextField("Type something...", text: $value)
        Spacer()
    }.ignoresSafeArea(.keyboard, edges: .bottom)
}
Run Code Online (Sandbox Code Playgroud)

两个垫片都用于垂直居中文本字段。

仅使用 GeometryReader 或ignoresSafeArea修饰符并不能解决问题,但是在将它们放在一起后(如上所示)最终停止了视图在键盘出现时向上移动。


小智 5

当我在其中使用 NavigationView 和 Stacks 时,我遇到过这样的情况,并且有几个本地“内容”视图。我也遇到了和作者一样的烦恼。我的解决方案 - GeometryReader 但非常重要 - 在NavigationView内部!代码如下:

NavigationView {
        GeometryReader { _ in
            VStack {
                // below VStacks
                textFieldsGroup
                buttonsGroup
                socialEnterGroup
                    .padding(.top, 40)
                Spacer()
            }
            .padding(.top, 20)
            .navigationTitle("Enter")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding()
            .ignoresSafeArea(.keyboard, edges: .bottom)
        }
    }
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助别人。