使用SwiftUI时如何隐藏键盘?

Hit*_*esh 29 ios swift swiftui

在以下情况下如何隐藏keyboard使用SwiftUI

情况1

我有TextField,我需要keyboard在用户单击return按钮时隐藏。

情况二

我有TextFieldkeyboard当用户在外面轻按时,我需要隐藏。

我该如何使用SwiftUI呢?

注意:

我尚未提出有关的问题UITextField。我想使用SwifUITextField)来做。

Mik*_*ail 72

经过多次尝试,我找到了一个(当前)不阻止任何控件的解决方案 - 将手势识别器添加到UIWindow.

  1. 如果您只想在外面的 Tap 上关闭键盘(不处理拖动) - 那么只需使用UITapGestureRecognizer并复制第 3 步:
  2. 创建适用于任何触摸的自定义手势识别器类:

    class AnyGestureRecognizer: UIGestureRecognizer {
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
            if let touchedView = touches.first?.view, touchedView is UIControl {
                state = .cancelled
    
            } else if let touchedView = touches.first?.view as? UITextView, touchedView.isEditable {
                state = .cancelled
    
            } else {
                state = .began
            }
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
           state = .ended
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
            state = .cancelled
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. SceneDelegate.swiftfunc scene,添加下一个代码:

    let tapGesture = AnyGestureRecognizer(target: window, action:#selector(UIView.endEditing))
    tapGesture.requiresExclusiveTouchType = false
    tapGesture.cancelsTouchesInView = false
    tapGesture.delegate = self //I don't use window as delegate to minimize possible side effects
    window?.addGestureRecognizer(tapGesture)  
    
    Run Code Online (Sandbox Code Playgroud)
  4. 实施UIGestureRecognizerDelegate以允许同时触摸。

    extension SceneDelegate: UIGestureRecognizerDelegate {
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在,任何视图上的任何键盘都将在触摸或向外拖动时关闭。

PS 如果您只想关闭特定的 TextFields - 然后在调用 TextField 回调时向窗口添加和删除手势识别器 onEditingChanged

  • 这个答案应该在顶部。当视图中存在其他控件时,其他答案将失败。 (3认同)
  • @DominiqueMiller 我为 iOS 14 改编了这个解决方案[此处](/sf/answers/4475944581/)。 (3认同)
  • 很棒的答案。工作完美。@Mikhail 实际上有兴趣知道如何专门针对某些文本字段删除手势识别器(我使用标签构建了一个自动完成功能,因此每次点击列表中的元素时,我不希望这个特定的文本字段失去焦点) (2认同)
  • @Mikhail您的解决方案非常好,但它“结束编辑”不仅针对键盘输入。我在尝试选择某些文本时遇到问题 - 我无法更改选择。每次我尝试移动光标(以扩大选择范围)时,选择都会消失。您是否可以修改“action:#selector(UIView.endEditing)”以仅隐藏键盘而不干扰文本选择? (2认同)

paw*_*222 52

SwiftUI 3 (iOS 15+)

(键盘上方的完成按钮)

从 iOS 15 开始,我们现在可以使用@FocusState来控制应该关注哪个字段(请参阅此答案以查看更多示例)。

我们也可以ToolbarItem直接在键盘上方添加s 。

当组合在一起时,我们可以Done在键盘正上方添加一个按钮。这是一个简单的演示:

在此处输入图片说明

struct ContentView: View {
    private enum Field: Int, CaseIterable {
        case username, password
    }

    @State private var username: String = ""
    @State private var password: String = ""

    @FocusState private var focusedField: Field?

    var body: some View {
        NavigationView {
            Form {
                TextField("Username", text: $username)
                    .focused($focusedField, equals: .username)
                SecureField("Password", text: $password)
                    .focused($focusedField, equals: .password)
            }
            .toolbar {
                ToolbarItem(placement: .keyboard) {
                    Button("Done") {
                        focusedField = nil
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

SwiftUI 2 (iOS 14+)

(点击任意位置隐藏键盘)

这是SwiftUI 2 / iOS 14的更新解决方案(最初由 Mikhail在此处提出)。

如果您使用 SwiftUI 生命周期,它不会使用缺少的AppDelegateSceneDelegate缺少的:

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear(perform: UIApplication.shared.addTapGestureRecognizer)
        }
    }
}

extension UIApplication {
    func addTapGestureRecognizer() {
        guard let window = windows.first else { return }
        let tapGesture = UITapGestureRecognizer(target: window, action: #selector(UIView.endEditing))
        tapGesture.requiresExclusiveTouchType = false
        tapGesture.cancelsTouchesInView = false
        tapGesture.delegate = self
        window.addGestureRecognizer(tapGesture)
    }
}

extension UIApplication: UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true // set to `false` if you don't want to detect tap during other gestures
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想检测其他手势(不仅是点击手势),您可以使用AnyGestureRecognizerMikhail 的回答

let tapGesture = AnyGestureRecognizer(target: window, action: #selector(UIView.endEditing))
Run Code Online (Sandbox Code Playgroud)

以下是如何检测除长按手势以外的同时手势的示例:

extension UIApplication: UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return !otherGestureRecognizer.isKind(of: UILongPressGestureRecognizer.self)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该位于顶部,因为要记住新的 SwiftUI 生命周期。 (4认同)
  • @RolandLariotte假设您使用iOS,您可以执行`guard let window = (connectedScenes.first as? UIWindowScene)?.windows.first else { return }`来消除警告。其行为与原始解决方案完全相同。 (3认同)
  • 这很好用。但是,如果我双击文本字段,而不是选择文本,键盘现在就会消失。知道如何允许双击进行选择吗? (2认同)
  • 为了回答我自己的问题,我将其设置回 true,然后设置 Mikhail 在他的答案中创建的 tapGesture= AnyGestureRecognizer(...),而不是 tapGesture=UITapGestureRecognizer(...)。这允许双击来选择文本字段内的文本,同时还允许各种手势将键盘隐藏在文本字段之外。 (2认同)
  • @pawello2222 不幸的是,iOS 15 解决方案不允许您点击键盘外部来关闭它。 (2认同)
  • @JAHelia .focused 修饰符也接受 bool ,因此如果您只有一个文本字段,则不必使用枚举。 (2认同)

Fel*_*dur 28

@RyanTCB 的回答很好;这里有一些改进,使其更易于使用并避免潜在的崩溃:

struct DismissingKeyboard: ViewModifier {
    func body(content: Content) -> some View {
        content
            .onTapGesture {
                let keyWindow = UIApplication.shared.connectedScenes
                        .filter({$0.activationState == .foregroundActive})
                        .map({$0 as? UIWindowScene})
                        .compactMap({$0})
                        .first?.windows
                        .filter({$0.isKeyWindow}).first
                keyWindow?.endEditing(true)                    
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

'错误修复'keyWindow!.endEditing(true)应该是正确的keyWindow?.endEditing(true)(是的,你可能会争辩说它不可能发生。)

更有趣的是如何使用它。例如,假设您有一个包含多个可编辑字段的表单。像这样包装它:

Form {
    .
    .
    .
}
.modifier(DismissingKeyboard())
Run Code Online (Sandbox Code Playgroud)

现在,点击任何本身不显示键盘的控件将进行适当的关闭。

(用 beta 7 测试)

  • 嗯 - 点击其他控件不再注册。事件被吞没了。 (8认同)

小智 27

我在 NavigationView 中使用 TextField 时遇到过这种情况。这是我的解决方案。当您开始滚动时,它将关闭键盘。

NavigationView {
    Form {
        Section {
            TextField("Receipt amount", text: $receiptAmount)
            .keyboardType(.decimalPad)
           }
        }
     }
     .gesture(DragGesture().onChanged{_ in UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)})
Run Code Online (Sandbox Code Playgroud)

  • 这将导致 onDelete(滑动删除)出现奇怪的行为。 (2认同)

rra*_*ael 26

您可以通过向共享应用程序发送操作来强制第一响应者辞职:

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以根据需要使用此方法关闭键盘:

struct ContentView : View {
    @State private var name: String = ""

    var body: some View {
        VStack {
            Text("Hello \(name)")
            TextField("Name...", text: self.$name) {
                // Called when the user tap the return button
                // see `onCommit` on TextField initializer.
                UIApplication.shared.endEditing()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想通过点击来关闭键盘,则可以通过点击操作创建全屏白色视图,这将触发endEditing(_:)

struct Background<Content: View>: View {
    private var content: Content

    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }

    var body: some View {
        Color.white
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        .overlay(content)
    }
}

struct ContentView : View {
    @State private var name: String = ""

    var body: some View {
        Background {
            VStack {
                Text("Hello \(self.name)")
                TextField("Name...", text: self.$name) {
                    self.endEditing()
                }
            }
        }.onTapGesture {
            self.endEditing()
        }
    }

    private func endEditing() {
        UIApplication.shared.endEditing()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `.keyWindow` 现已弃用。请参阅[Lorenzo Santini 的回答](/sf/answers/4034773011/)。 (2认同)
  • 另外,.tapAction已重命名为.onTapGesture。 (2认同)
  • 也许还值得注意的是,“UIApplication”是 UIKit 的一部分,因此需要“导入 UIKit”。 (2认同)

Pta*_*tah 16

从 iOS 15 开始,您可以使用@FocusState

struct ContentView: View {
    
    @Binding var text: String
    
    private enum Field: Int {
        case yourTextEdit
    }

    @FocusState private var focusedField: Field?

    var body: some View {
        VStack {
            TextEditor(text: $speech.text.bound)
                .padding(Edge.Set.horizontal, 18)
                .focused($focusedField, equals: .yourTextEdit)
        }.onTapGesture {
            if (focusedField != nil) {
                focusedField = nil
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Vic*_*rov 13

我的解决方案如何在用户点击外部时隐藏软件键盘。您需要使用contentShapewithonLongPressGesture来检测整个 View 容器。onTapGesture需要避免阻塞焦点TextField。您可以使用onTapGesture代替,onLongPressGesture但 NavigationBar 项目将不起作用。

extension View {
    func endEditing() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

struct KeyboardAvoiderDemo: View {
    @State var text = ""
    var body: some View {
        VStack {
            TextField("Demo", text: self.$text)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .contentShape(Rectangle())
        .onTapGesture {}
        .onLongPressGesture(
            pressing: { isPressed in if isPressed { self.endEditing() } },
            perform: {})
    }
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*tto 13

在 iOS15 中,此功能完美运行。

VStack {
    // Some content
}
.onTapGesture {
    // Hide Keyboard
    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
.gesture(
    DragGesture(minimumDistance: 0, coordinateSpace: .local).onEnded({ gesture in
        // Hide keyboard on swipe down
        if gesture.translation.height > 0 {
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
}))
Run Code Online (Sandbox Code Playgroud)

您的文本字段上不需要任何其他内容,向下滑动和点击都可以隐藏它。我使用它的方式是在我的 master 上NavigationView添加此代码,然后它下面的所有内容都会起作用。唯一的例外是任何都Sheet需要将其附加到它后面,因为它作用于不同的状态。


Lor*_*ini 10

我找到了另一种不需要访问该keyWindow属性的方法来关闭键盘。事实上,编译器会使用

UIApplication.shared.keyWindow?.endEditing(true)
Run Code Online (Sandbox Code Playgroud)

iOS 13.0中已弃用“ keyWindow”:不应将其用于支持多个场景的应用程序,因为它会返回所有已连接场景的关键窗口

相反,我使用了以下代码:

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)
Run Code Online (Sandbox Code Playgroud)


Geo*_*kov 9

我更喜欢使用.onLongPressGesture(minimumDuration: 0),它不会在TextView激活另一个键盘时导致键盘闪烁( 的副作用.onTapGesture)。隐藏键盘代码可以是可重复使用的功能。

.onTapGesture(count: 2){} // UI is unresponsive without this line. Why?
.onLongPressGesture(minimumDuration: 0, maximumDistance: 0, pressing: nil, perform: hide_keyboard)

func hide_keyboard()
{
    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
Run Code Online (Sandbox Code Playgroud)


jos*_*zal 9

纯 SwiftUI (iOS 15)

iOS 15 (Xcode 13) 中的 SwiftUI 获得了对TextField使用新@FocusState属性包装器的编程重点的原生支持。

要关闭键盘,只需将视图设置focusedFieldnil。返回键将自动关闭键盘(自 iOS 14 起)。

文档:https : //developer.apple.com/documentation/swiftui/focusstate/

struct MyView: View {

    enum Field: Hashable {
        case myField
    }

    @State private var text: String = ""
    @FocusState private var focusedField: Field?

    var body: some View {
        TextField("Type here", text: $text)
            .focused($focusedField, equals: .myField)

        Button("Dismiss") {
            focusedField = nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

纯 SwiftUI(iOS 14 及以下)

您可以完全避免与 UIKit 交互并在纯 SwiftUI 中实现它。只需.id(<your id>)向您添加一个修饰符TextField并在您想要关闭键盘时更改其值(滑动、查看点击、按钮操作等)。

示例实现:

struct MyView: View {
    @State private var text: String = ""
    @State private var textFieldId: String = UUID().uuidString

    var body: some View {
        VStack {
            TextField("Type here", text: $text)
                .id(textFieldId)

            Spacer()

            Button("Dismiss", action: { textFieldId = UUID().uuidString })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我仅在最新的 Xcode 12 beta 中对其进行了测试,但它应该适用于旧版本(甚至 Xcode 11)而不会出现任何问题。


Rya*_*TCB 8

将此修饰符添加到要检测用户点击的视图中

.onTapGesture {
            let keyWindow = UIApplication.shared.connectedScenes
                               .filter({$0.activationState == .foregroundActive})
                               .map({$0 as? UIWindowScene})
                               .compactMap({$0})
                               .first?.windows
                               .filter({$0.isKeyWindow}).first
            keyWindow!.endEditing(true)

        }
Run Code Online (Sandbox Code Playgroud)


Dim*_*ovo 8

只需在'SceneDelegate.swift'文件中添加SwiftUI.onTapGesture {window.endEditing(true)}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(
                rootView: contentView.onTapGesture { window.endEditing(true)}
            )
            self.window = window
            window.makeKeyAndVisible()
        }
    }
Run Code Online (Sandbox Code Playgroud)

这对于使用应用程序中的键盘的每个视图就足够了...

  • 这带来了另一个问题 - 我在表单{}旁边的文本字段中有一个选择器,它变得没有响应。我没有使用本主题中的所有答案找到解决方案。但如果您不使用选择器,您的答案对于在其他地方点击即可关闭键盘是一个很好的选择。 (5认同)
  • 再次嗨,目前我有两个解决方案:第一个 - 是使用返回按钮上关闭的本机键盘,第二个 - 稍微更改点击处理(又名“костыль”) - window.rootViewController = UIHostingController(rootView : contentView.onTapGesture(count: 2, Perform: { window.endEditing(true) }) ) 希望这对你有帮助... (2认同)

Has*_*Ali 8

通过上面的 josefdolezal扩展答案,当用户点击文本字段之外的任何位置时,您可以隐藏键盘,如下所示:

struct SwiftUIView: View {
        @State private var textFieldId: String = UUID().uuidString // To hidekeyboard when tapped outside textFields
        @State var fieldValue = ""
        var body: some View {
            VStack {
                TextField("placeholder", text: $fieldValue)
                    .id(textFieldId)
                    .onTapGesture {} // So that outer tap gesture has no effect on field

                // any more views

            }
            .onTapGesture { // whenever tapped within VStack
                textFieldId = UUID().uuidString 
               //^ this will remake the textfields hence loosing keyboard focus!
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


Moj*_*ini 7

键盘Return按键

除了有关点击文本字段外部的所有答案之外,您可能还想在用户点击键盘上的返回键时关闭键盘:

定义这个全局函数:

func resignFirstResponder() {
    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
Run Code Online (Sandbox Code Playgroud)

并在onCommit参数 it 中添加 use :

TextField("title", text: $text, onCommit:  {
    resignFirstResponder()
})
Run Code Online (Sandbox Code Playgroud)

好处

  • 您可以从任何地方调用它
  • 它不依赖于 UIKit 或 SwiftUI(可以在 Mac 应用程序中使用)
  • 即使在 iOS 13 中也能正常工作

演示

演示


msk*_*msk 6

因为keyWindow已弃用。

extension View {
    func endEditing(_ force: Bool) {
        UIApplication.shared.windows.forEach { $0.endEditing(force)}
    }
}
Run Code Online (Sandbox Code Playgroud)


Saj*_*jon 6

扩展@Feldur(基于@RyanTCB)的答案,这是一个更具表现力和更强大的解决方案,允许您在其他手势上关闭键盘onTapGesture,您可以在函数调用中指定您想要的手势。

用法

// MARK: - View
extension RestoreAccountInputMnemonicScreen: View {
    var body: some View {
        List(viewModel.inputWords) { inputMnemonicWord in
            InputMnemonicCell(mnemonicInput: inputMnemonicWord)
        }
        .dismissKeyboard(on: [.tap, .drag])
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用All.gestures(只是糖Gestures.allCases

.dismissKeyboard(on: All.gestures)
Run Code Online (Sandbox Code Playgroud)

代码

enum All {
    static let gestures = all(of: Gestures.self)

    private static func all<CI>(of _: CI.Type) -> CI.AllCases where CI: CaseIterable {
        return CI.allCases
    }
}

enum Gestures: Hashable, CaseIterable {
    case tap, longPress, drag, magnification, rotation
}

protocol ValueGesture: Gesture where Value: Equatable {
    func onChanged(_ action: @escaping (Value) -> Void) -> _ChangedGesture<Self>
}
extension LongPressGesture: ValueGesture {}
extension DragGesture: ValueGesture {}
extension MagnificationGesture: ValueGesture {}
extension RotationGesture: ValueGesture {}

extension Gestures {
    @discardableResult
    func apply<V>(to view: V, perform voidAction: @escaping () -> Void) -> AnyView where V: View {

        func highPrio<G>(
             gesture: G
        ) -> AnyView where G: ValueGesture {
            view.highPriorityGesture(
                gesture.onChanged { value in
                    _ = value
                    voidAction()
                }
            ).eraseToAny()
        }

        switch self {
        case .tap:
            // not `highPriorityGesture` since tapping is a common gesture, e.g. wanna allow users
            // to easily tap on a TextField in another cell in the case of a list of TextFields / Form
            return view.gesture(TapGesture().onEnded(voidAction)).eraseToAny()
        case .longPress: return highPrio(gesture: LongPressGesture())
        case .drag: return highPrio(gesture: DragGesture())
        case .magnification: return highPrio(gesture: MagnificationGesture())
        case .rotation: return highPrio(gesture: RotationGesture())
        }

    }
}

struct DismissingKeyboard: ViewModifier {

    var gestures: [Gestures] = Gestures.allCases

    dynamic func body(content: Content) -> some View {
        let action = {
            let forcing = true
            let keyWindow = UIApplication.shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .map({$0 as? UIWindowScene})
                .compactMap({$0})
                .first?.windows
                .filter({$0.isKeyWindow}).first
            keyWindow?.endEditing(forcing)
        }

        return gestures.reduce(content.eraseToAny()) { $1.apply(to: $0, perform: action) }
    }
}

extension View {
    dynamic func dismissKeyboard(on gestures: [Gestures] = Gestures.allCases) -> some View {
        return ModifiedContent(content: self, modifier: DismissingKeyboard(gestures: gestures))
    }
}
Run Code Online (Sandbox Code Playgroud)

警告语

请注意,如果您使用所有手势,它们可能会发生冲突,并且我没有想出任何巧妙的解决方案来解决这个问题。


Ser*_*ost 6

我发现效果很好的是

 extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后添加到视图结构中:

 private func endEditing() {
    UIApplication.shared.endEditing()
}
Run Code Online (Sandbox Code Playgroud)

然后

struct YourView: View {
    var body: some View {
       ParentView {
           //...
       }.contentShape(Rectangle()) //<---- This is key!
        .onTapGesture {endEditing()} 
     }
 }
    
Run Code Online (Sandbox Code Playgroud)

  • 此代码禁用视图上的其他触摸操作。 (3认同)

zer*_*nna 5

似乎endEditing解决方案是@rraphael 指出的唯一解决方案。
到目前为止我见过的最干净的例子是这样的:

extension View {
    func endEditing(_ force: Bool) {
        UIApplication.shared.keyWindow?.endEditing(force)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在 onCommit:

  • `.keyWindow` 现已弃用。请参阅[Lorenzo Santini 的回答](/sf/answers/4034773011/)。 (3认同)

Mic*_*nry 5

请检查https://github.com/michaelhenry/KeyboardAvoider

只需包含KeyboardAvoider {}在您的主视图之上即可。

KeyboardAvoider {
    VStack { 
        TextField()
        TextField()
        TextField()
        TextField()
    }

}
Run Code Online (Sandbox Code Playgroud)