没有简单的方法,但 IMO 最好的选择是添加一个工具栏,如图所示 here:
import SwiftUI
struct ContentView: View {
@State private var phoneNumber = ""
var body: some View {
NavigationView {
KeyboardView {
HStack {
Spacer()
TextField("Phone Number", text: $phoneNumber)
.padding()
.overlay(RoundedRectangle(cornerRadius: 8)
.stroke(Color.secondary, lineWidth: 1)
.frame(height: 50))
.keyboardType(.phonePad)
Spacer()
}
} toolBar: {
HStack {
Spacer()
Button {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
} label: { Text("Done") }
}.padding()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class KeyboardResponder: ObservableObject {
private var notificationCenter: NotificationCenter
@Published private(set) var height: CGFloat = .zero
init(center: NotificationCenter = .default) {
notificationCenter = center
notificationCenter.addObserver(self, selector: #selector(keyBoardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(keyBoardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
func dismiss() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
deinit { notificationCenter.removeObserver(self) }
@objc func keyBoardWillShow(_ notification: Notification) {
height = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height ?? .zero
}
@objc func keyBoardWillHide(_ notification: Notification) {
height = .zero
}
}
struct KeyboardView<Content, ToolBar>: View where Content: View, ToolBar: View {
@StateObject private var keyboard = KeyboardResponder()
let toolbarFrame = CGSize(width: UIScreen.main.bounds.width, height: 40)
var content: () -> Content
var toolBar: () -> ToolBar
var body: some View {
ZStack {
content().padding(.bottom, keyboard.height == .zero ? .zero : toolbarFrame.height)
VStack {
Spacer()
toolBar()
.frame(width: toolbarFrame.width, height: toolbarFrame.height)
.background(Color.secondary)
}
.opacity(keyboard.height == .zero ? .zero : 1)
.animation(.easeOut)
}
.padding(.bottom, keyboard.height)
.edgesIgnoringSafeArea(.bottom)
.animation(.easeOut)
}
}