问题在于用“TabaView”的页,我确实增加了一个变体,这样,当关键板看上去时,就把这一观点推到关键板上。
import SwiftUI
//import Combine
struct KeyboardResponsiveModifier: ViewModifier {
/*
IMPORTANT: I had an issue using the .tabViewStyle(.page) on TabView; issue was when I clicked on the
TextField in the TabView the keyboard would block the TextField, this struct help solve that issue, by
moving the view up so that when the keyboard appears it doesn t block the textField
*/
@State private var textFieldPosition: CGFloat = 0
@State private var textFieldHeight: CGFloat = 0
@State private var offset: CGFloat = 0
func body(content: Content) -> some View {
content
.padding(.bottom, offset)
.overlay(
GeometryReader { proxy in
Color.clear
.onAppear {
textFieldPosition = proxy.frame(in: .global).minY
textFieldHeight = proxy.size.height
}
}
)
.onAppear(perform: subscribeToKeyboardEvents)
}
private func calculateOffset(with keyboardHeight: CGFloat, screenHeight: CGFloat) -> CGFloat {
let adjustedPosition = screenHeight - textFieldPosition - textFieldHeight
let newOffset = keyboardHeight - adjustedPosition
return newOffset
}
private func subscribeToKeyboardEvents() {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { notification in
guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
let screenHeight = UIScreen.main.bounds.height
let keyboardHeight = keyboardFrame.height
// withAnimation(.linear(duration: 0.05)) {
// when the keyboard popups up moves the view up so that the TextField is visible above the keyboard
offset = calculateOffset(with: keyboardHeight, screenHeight: screenHeight)
// }
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
// withAnimation(.linear(duration: 0.05)) {
offset = 0 // when the keyboard disappears it moves the view back down
// }
}
}
}
extension View {
func keyboardResponsive() -> some View {
self.modifier(KeyboardResponsiveModifier())
}
}
struct TextView: View {
@State var textInput = ""
@State private var isKeyboardVisible = false
var body: some View {
ScrollViewReader { proxy in
GeometryReader { geometry in
ScrollView {
VStack{
Spacer()
TextField("Prompt", text: $textInput, axis: .vertical)
.padding(EdgeInsets(top: 10, leading: 15, bottom: 10, trailing: 15))
.overlay(
RoundedRectangle(cornerRadius: 14)
.stroke(Color.red, lineWidth: 1)
)
.autocapitalization(.none) //stops the auto capitilize of words
.autocorrectionDisabled()
.foregroundColor(Color.black)
.padding( .bottom, isKeyboardVisible ? 10 : 0) // give a little padding when the keyboard appears
.id("TextFieldID")
}
.frame(width: geometry.size.width, height: geometry.size.height)
}
.keyboardResponsive() // Apply the custom modifier here
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { _ in
isKeyboardVisible = true
withAnimation { // scroll to the bottom so that it doesn t appear as tho the keyboard is overlapping the TextField
proxy.scrollTo("TextFieldID", anchor: .bottom)
}
}
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
isKeyboardVisible = false
}
}
}
}
}
#Preview {
TextView()
}