V8tr / KeyboardAvoidanceSwiftUI

How to move SwiftUI view up when keyboard appears https://www.vadimbulavin.com/how-to-move-swiftui-view-when-keyboard-covers-text-field/
https://www.vadimbulavin.com
The Unlicense
327 stars 36 forks source link

Difference in behavior between iOS 13 and 14 #8

Open avi-screenovate opened 3 years ago

avi-screenovate commented 3 years ago

Screen Shot 2021-02-03 at 9 48 47

The screenshot shows two simulators for iPhone 8: one running iOS 13.7 and the other 14.4. The code is identical between them, run from Xcode directly. I have verified the same behavior on a physical iOS 14 device.

In case it matters, the text field is actually hidden, and is in a ZStack with the button on the bottom, to make sure it forces the button to move up above the keyboard. During normal operation, the keyboard is never hidden, though of course we can do so in the simulator.

avi-screenovate commented 3 years ago

For anyone that needs this: I figured out that iOS 14 automatically changes the size of a VStack for the keyboard, making this modifier unnecessary.

I made the following change to KeyboardAdaptive.body(content:):

    func body(content: Content) -> some View {
        GeometryReader { (geometry) -> AnyView in
            if #available(iOS 14, *) {
                return AnyView(content)
            }

            return AnyView(content
                            .padding(.bottom, self.bottomPadding)
                            .onReceive(Publishers.keyboardHeight) { keyboardHeight in
                                let keyboardTop = geometry.frame(in: .global).height - keyboardHeight
                                let focusedTextInputBottom = UIResponder.currentFirstResponder?.globalFrame?.maxY ?? 0
                                self.bottomPadding = max(0, focusedTextInputBottom - keyboardTop - geometry.safeAreaInsets.bottom)
                            }
                            .animation(.easeOut(duration: 0.16))
            )
        }
    }
ben-p-commits commented 2 years ago

Update for iOS 15:

content
      .padding(.bottom, self.bottomPadding)
      .onReceive(Publishers.keyboardHeight) { keyboardHeight in
          let keyboardTop = geometry.frame(in: .global).height - min(0, keyboardHeight) // putting a floor on negative keyboard hight fixes a similar issue on iOS 15
          let focusedTextInputBottom = UIResponder.currentFirstResponder?.globalFrame?.maxY ?? 0
          self.bottomPadding = max(0, focusedTextInputBottom - keyboardTop)
  }
  .animation(.easeOut(duration: 0.25))
Adarsh0Ranjan commented 1 year ago

view is getting scrolled bit more..if the view is complex