You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 14.2+键盘工具栏覆盖TextField问题求助

解决SwiftUI TextField被键盘输入附件栏遮挡的问题

iOS 14.2+的默认键盘避让逻辑确实未包含输入附件栏的高度,导致TextField会被带附件栏的键盘遮挡。可以通过以下两种方法解决:

方法一:监听键盘完整高度(含附件栏)并调整布局

通过监听系统键盘通知,获取包含附件栏的完整键盘高度,动态调整TextField的底部内边距:

  1. 实现键盘高度监听的ViewModifier和扩展:
import Combine
import SwiftUI

struct KeyboardAdaptive: ViewModifier {
    @State private var keyboardHeight: CGFloat = 0
    
    func body(content: Content) -> some View {
        content
            .padding(.bottom, keyboardHeight)
            .onReceive(Publishers.keyboardHeight) { height in
                keyboardHeight = height
            }
    }
}

extension Publishers {
    static var keyboardHeight: AnyPublisher<CGFloat, Never> {
        let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
            .map { $0.keyboardHeight }
        
        let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification)
            .map { _ in 0 }
        
        return MergeMany(willShow, willHide)
            .eraseToAnyPublisher()
    }
}

extension Notification {
    var keyboardHeight: CGFloat {
        (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
    }
}
  1. 在你的TextField上应用该Modifier:
TextField("Add a comment", text: $text, axis: .vertical)
    .multilineTextAlignment(.leading)
    .foregroundColor(.white)
    .keyboardType(.default)
    .submitLabel(.done)
    .padding([.top, .bottom], 8)
    .padding([.horizontal], 16)
    .background(Color.black.opacity(0.7))
    .modifier(KeyboardAdaptive()) // 新增这一行

方法二:使用ScrollView自动调整

将整个布局包裹在ScrollView中,利用ScrollView的自动键盘避让特性,确保TextField不会被遮挡:

struct CommentView: View {
    @State var text = ""
    @FocusState private var isFocused: Bool

    var body: some View {
        ScrollView {
            VStack {
                // 用minLength模拟原布局的Spacer高度,适配不同屏幕
                Spacer(minLength: UIScreen.main.bounds.height - 500)
                Image(uiImage: UIImage(named: "dog.jpeg")!)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: 350, height: 500)
                    .overlay(alignment: .center) {
                        VStack {
                            Spacer()
                            TextField("Add a comment", text: $text, axis: .vertical)
                                .multilineTextAlignment(.leading)
                                .foregroundColor(.white)
                                .keyboardType(.default)
                                .submitLabel(.done)
                                .padding([.top, .bottom], 8)
                                .padding([.horizontal], 16)
                                .background(Color.black.opacity(0.7))
                                .focused($isFocused)
                        }
                    }
                    .clipShape(RoundedRectangle(cornerRadius: 20))
            }
        }
        .scrollDismissesKeyboard(.interactively)
    }
}

两种方法中,方法一的适配性更强,适用于各种布局场景;方法二更简洁,适合本身可以用ScrollView承载的布局。

内容的提问来源于stack exchange,提问作者bli00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:26:11