0

Before you mark this like duplicate please read the following

I'm trying to make an iPhone and iPad app, and i have this common issue with the keyboard overlapping the text input. i tried all most every solution from this site but I didn't find one how it works for-me so I'm using this solution Move TextField up when the keyboard has appeared in SwiftUI

Works great on iPhone but the problem comes on the iPad, my view is in a sheet so in the iPad the sheet is like a windows so I'm trying to solve this like follow

  • get the screen size
  • get with geometry reader of my view Size
  • get the keyboard size
  • math the difference of size to adjust the padding keyboardsize - ((screensize - viewSize)/2)

this is the code

import SwiftUI

final class KeyboardResponder: ObservableObject {
    private var notificationCenter: NotificationCenter
    @Published private(set) var currentHeight: CGFloat = 0
    let screenHeight = UIScreen.main.bounds.size.height

    init(center: NotificationCenter = .default) {
        notificationCenter = center
        notificationCenter.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }

    deinit {
        notificationCenter.removeObserver(self)
    }

    @objc func keyBoardWillShow(notification: Notification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            currentHeight = keyboardSize.height
        }
    }

    @objc func keyBoardWillHide(notification: Notification) {
        currentHeight = 0
    }
}

struct sheetView: View {
    @State private var text1 = ""
    @State private var text2 = ""
    @State private var text3 = ""

    @State private var text4 = ""
    @State private var text5 = ""
    @State private var text6 = ""

    @State private var text7 = ""
    @State private var text8 = ""
    @State private var text9 = ""

    @State private var text10 = ""
    @State private var text11 = ""
    @State private var text12 = ""

    @ObservedObject private var keyboard = KeyboardResponder()
    let screenHeight = UIScreen.main.bounds.size.height

    @Environment(\.horizontalSizeClass) var sizeClass

    var body: some View{

        GeometryReader { geo in
            NavigationView{

                Group{
                    if self.sizeClass == .compact {

                        List{
                            Section(header: Text("test header")){
                                TextField("Test 1", text: self.$text1)
                                TextField("Test 2", text: self.$text2)
                                TextField("Test 3", text: self.$text3)
                                TextField("Test 4", text: self.$text4)
                            }

                            Section(header: Text("test header 2")){
                                TextField("Test 5", text: self.$text5)
                                TextField("Test 6", text: self.$text6)
                                TextField("Test 7", text: self.$text7)
                                TextField("Test 8", text: self.$text8)
                            }

                            Section(header: Text("test header 3")){
                                TextField("Test 9", text: self.$text9)
                                TextField("Test 10", text: self.$text10)
                                TextField("Test 11", text: self.$text11)
                                TextField("Test 12", text: self.$text12)
                            }
                            Section(header: Text("test header")){
                                TextField("Test 1", text: self.$text1)
                                TextField("Test 2", text: self.$text2)
                                TextField("Test 3", text: self.$text3)
                                TextField("Test 4", text: self.$text4)
                            }

                            Section(header: Text("test header 2")){
                                TextField("Test 5", text: self.$text5)
                                TextField("Test 6", text: self.$text6)
                                TextField("Test 7", text: self.$text7)
                                TextField("Test 8", text: self.$text8)
                            }

                            Section(header: Text("test header 3")){
                                TextField("Test 9", text: self.$text9)
                                TextField("Test 10", text: self.$text10)
                                TextField("Test 11", text: self.$text11)
                                TextField("Test 12", text: self.$text12)
                            }

                        }
                        .listStyle(GroupedListStyle())
                        .environment(\.horizontalSizeClass, .regular)
                        .padding(.bottom, self.keyboard.currentHeight)
                        .edgesIgnoringSafeArea(.bottom)
                        .animation(.easeOut(duration: 0.16))
                    } else {
                        List{
                            Section(header: Text("test header")){
                                TextField("Test 1", text: self.$text1)
                                TextField("Test 2", text: self.$text2)
                                TextField("Test 3", text: self.$text3)
                                TextField("Test 4", text: self.$text4)
                            }

                            Section(header: Text("test header 2")){
                                TextField("Test 5", text: self.$text5)
                                TextField("Test 6", text: self.$text6)
                                TextField("Test 7", text: self.$text7)
                                TextField("Test 8", text: self.$text8)
                            }

                            Section(header: Text("test header 3")){
                                TextField("Test 9", text: self.$text9)
                                TextField("Test 10", text: self.$text10)
                                TextField("Test 11", text: self.$text11)
                                TextField("Test 12", text: self.$text12)
                            }
                            Section(header: Text("test header")){
                                TextField("Test 1", text: self.$text1)
                                TextField("Test 2", text: self.$text2)
                                TextField("Test 3", text: self.$text3)
                                TextField("Test 4", text: self.$text4)
                            }

                            Section(header: Text("test header 2")){
                                TextField("Test 5", text: self.$text5)
                                TextField("Test 6", text: self.$text6)
                                TextField("Test 7", text: self.$text7)
                                TextField("Test 8", text: self.$text8)
                            }

                            Section(header: Text("test header 3")){
                                TextField("Test 9", text: self.$text9)
                                TextField("Test 10", text: self.$text10)
                                TextField("Test 11", text: self.$text11)
                                TextField("Test 12", text: self.$text12)
                            }

                        }
                        .listStyle(GroupedListStyle())
                        .environment(\.horizontalSizeClass, .regular)
                        .padding(.bottom, (self.keyboard.currentHeight > 0) ? (self.keyboard.currentHeight - ((self.screenHeight - geo.size.height)/2)): self.keyboard.currentHeight )
                        .edgesIgnoringSafeArea(.bottom)
                        .animation(.easeOut(duration: 0.16))
                    }

                }

            .navigationBarTitle("Test")
            }
        }


    }

}

struct ContentView: View {
    @State private var showSheet = false
    var body: some View {
        VStack{
            Button(action : {
                self.showSheet = true
            }){
               Text("Show Sheet")
            }
            .sheet(isPresented: $showSheet) {
                sheetView()
                .environment(\.horizontalSizeClass, .compact)
            }

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

now in the iPhone is working good but I have a little issue in the landScape I think is more a list padding problem, but the real problem is the sheet on iPad on portrait for some reason the sheet its push up when the keyboard appears so it mess up all the maths.

also I getting and safe are padding white line even if a adding ignore safe area to the iPad view

enter image description here

enter image description here

  1. So I'm just trying to avoid overlapping of the keyboard if you know a simple or elegant solution I really want to read about

  2. also it would be helpful to know if I can calculate the padding or size of the sheet to add the right padding no Matter the orientation of the device

  3. and also if you have a clue about why is padding keep breaking on the landscape view of the list not the iPhone it would be really helpful

Misael Landeros
  • 545
  • 5
  • 18

1 Answers1

2

Have you tried using the library https://github.com/hackiftekhar/IQKeyboardManager. You can easily add it to swiftUI projects as posted here, https://github.com/hackiftekhar/IQKeyboardManager/issues/1606.

It has worked for me so far but i have not tested it on an ipad.

BokuWaTaka
  • 168
  • 6