Pindahkan bidang teks saat keyboard muncul cepat

217

Saya menggunakan Swift untuk pemrograman dengan iOS dan saya menggunakan kode ini untuk memindahkan UITextField, tetapi tidak berfungsi. Saya memanggil fungsi keyboardWillShowdengan benar, tetapi bidang teks tidak bergerak. Saya menggunakan pembayaran otomatis.

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self);
}

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        //let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)

        var frame = self.ChatField.frame
        frame.origin.y = frame.origin.y - keyboardSize.height + 167
        self.chatField.frame = frame
        println("asdasd")
    }
}
Pedro Manfredi
sumber
2
Panduan penelusuran dengan file-file Proyek: codebeaulieu.com/43/…
Dan Beaulieu
Mungkin deinit dan viewDidLoad tidak seimbang.
Ricardo
Berdasarkan pada dokumen Apple dan pengalaman pribadi. Inilah repo git saya menggunakan UIScrollView untuk memindahkan TF: github.com/29satnam/MoveTextFieldWhenKeyboardAppearsSwift
Codetard

Jawaban:

315

Ada beberapa perbaikan yang harus dilakukan pada jawaban yang ada.

Pertama, UIKeyboardWillChangeFrameNotification mungkin adalah notifikasi terbaik karena menangani perubahan yang tidak hanya menampilkan / menyembunyikan tetapi juga perubahan karena perubahan keyboard (bahasa, menggunakan keyboard pihak ke-3 dll.) Dan rotasi juga (tetapi komentar di bawah ini menunjukkan bahwa keyboard akan disembunyikan jika harus juga ditangani untuk mendukung koneksi keyboard perangkat keras).

Kedua, parameter animasi dapat ditarik dari notifikasi untuk memastikan bahwa animasi disatukan dengan benar.

Mungkin ada opsi untuk membersihkan kode ini sedikit lebih terutama jika Anda merasa nyaman dengan membuka bungkusan kode kamus.

Cepat 3

class MyViewController: UIViewController {

// This constraint ties an element at zero points from the bottom layout guide
@IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint?

override func viewDidLoad() {
    super.viewDidLoad()
    // Note that SO highlighting makes the new selector syntax (#selector()) look
    // like a comment but it isn't one
    NotificationCenter.default.addObserver(self,
        selector: #selector(self.keyboardNotification(notification:)),
        name: NSNotification.Name.UIKeyboardWillChangeFrame,
        object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardNotification(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let endFrameY = endFrame.origin.y ?? 0
        let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
        if endFrameY >= UIScreen.main.bounds.size.height {
            self.keyboardHeightLayoutConstraint?.constant = 0.0
        } else {
            self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0
        }
        UIView.animate(withDuration: duration,
                                   delay: TimeInterval(0),
                                   options: animationCurve,
                                   animations: { self.view.layoutIfNeeded() },
                                   completion: nil)
    }
}

(Diedit ke akun untuk keyboard yang menghidupkan layar bukan mengecil, sesuai dengan komentar luar biasa @ Gabox di bawah)

Cepat 5

class MyViewController: UIViewController {

// This constraint ties an element at zero points from the bottom layout guide
@IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint?

override func viewDidLoad() {
    super.viewDidLoad()
    // Note that SO highlighting makes the new selector syntax (#selector()) look
    // like a comment but it isn't one
    NotificationCenter.default.addObserver(self,
        selector: #selector(self.keyboardNotification(notification:)),
        name: UIResponder.keyboardWillChangeFrameNotification,
        object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardNotification(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let endFrameY = endFrame?.origin.y ?? 0
        let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
        if endFrameY >= UIScreen.main.bounds.size.height {
            self.keyboardHeightLayoutConstraint?.constant = 0.0
        } else {
            self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0
        }
        UIView.animate(withDuration: duration,
                                   delay: TimeInterval(0),
                                   options: animationCurve,
                                   animations: { self.view.layoutIfNeeded() },
                                   completion: nil)
    }
}
Joseph Lord
sumber
1
@ JosephLord bagus. tapi saya menemukan ini tidak berfungsi ketika keyboard bersembunyi karena endFrame?.size.heighttidak ada nihil. Saya mendapat bingkai akhir sebagai UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 1024}, {768, 264}}";. Berlari di iOS 8.3 iPad Simulator, Portrait. Xcode6.3 beta4.
Hlung
8
jika keyboard tidak bersembunyi, coba gunakan kode ini jika endFrame? .origin.y> = UIScreen.mainScreen (). bounds.size.height {self.keyboardHeightLayoutConstraint? .constant = 0.0} else {self.keyboardHeightLayoutConstraint? .constant = endFrame.size.height}
Gabriel Goncalves
3
keyBoardHeightLayoutConstraint adalah kendala yang didefinisikan dalam InterfaceBuilder membatasi bagian bawah tampilan yang ingin Anda pindahkan / susutkan ke panduan tata letak bawah atau bagian bawah tampilan utama untuk viewcontroller. Konstanta awalnya diatur ke nol dan akan disesuaikan untuk memberikan ruang bagi keyboard ketika keyboard muncul atau mengubah ukuran.
Joseph Lord
2
Catatan yang .UIKeyboardWillChangeFrametidak menyala ketika keyboard perangkat keras terhubung, meskipun keyboard iOS menghilang. Anda perlu mengamati .UIKeyboardWillHidejuga untuk menangkap kasing tepi itu.
jamesk
1
@Sulthan berfungsi dengan baik .. Masalah saya adalah mendapatkan sedikit lebih tinggi dari keybaord. adakah cara untuk memperbaikinya?
Pavlos
128

Jika Anda menggunakan Tata Letak Otomatis, saya berasumsi Anda telah menetapkan Batas Bawah untuk batasan Superview . Jika itu masalahnya, Anda hanya perlu memperbarui nilai kendala. Begini cara Anda melakukannya dengan sedikit animasi.

func keyboardWasShown(notification: NSNotification) {
    let info = notification.userInfo!
    let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()

    UIView.animateWithDuration(0.1, animations: { () -> Void in
        self.bottomConstraint.constant = keyboardFrame.size.height + 20
    })
}

Hardcoded 20 ditambahkan hanya untuk memunculkan textfield sedikit di atas keyboard. Kalau tidak, margin atas keyboard dan margin bawah textfield akan menyentuh.

Saat keyboard diberhentikan, setel ulang nilai kendala ke nilai aslinya.

Isuru
sumber
1
Bisakah Anda jelaskan saya bagaimana saya mendefinisikannya? Terima kasih! saya selalu mengontrol semua di storyboard
Pedro Manfredi
4
bottomConstraint adalah nama yang saya berikan kepada kendala. Saya memilih batasan, menyeret dan membuat IBOutlet untuknya dan memberikan nama itu. Anda dapat membuat IBOutlets ke batasan seperti yang dapat Anda lakukan dengan elemen UI lainnya seperti tombol dan bidang teks.
Isuru
2
Jawaban ini bekerja dengan baik kecuali animasi terjadi segera untuk saya. Periksa Bagaimana cara menganimasikan perubahan kendala? untuk cara menghidupkan dengan benar.
Adam Johns
2
@ vinbhai4u Anda harus mendaftar untuk UIKeyboardWillShowNotificationpemberitahuan. Lihatlah kode dalam pertanyaan OP.
Isuru
8
@AdamJohns Untuk menghidupkan perubahan kendala, perbarui konstanta di luar animateWithDurationdan panggil self.view.layoutIfNeeded()di dalam blok animate.
Maks.
110

Solusi sederhana adalah menggerakkan tampilan ke atas dengan ketinggian keyboard konstan.

override func viewDidLoad() {
   super.viewDidLoad()        
   NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
   NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}

@objc func keyboardWillShow(sender: NSNotification) {
     self.view.frame.origin.y = -150 // Move view 150 points upward 
}

@objc func keyboardWillHide(sender: NSNotification) {
     self.view.frame.origin.y = 0 // Move view to original position  
}

Swift 5:

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(sender:)), name: UIResponder.keyboardWillShowNotification, object: nil);

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(sender:)), name: UIResponder.keyboardWillHideNotification, object: nil);
Saqib Omer
sumber
4
Saya suka solusi sederhana ini. Tapi saya menambahkan boolean keyboardShowing karena saya telah pindah dari satu bidang teks. Saya hanya memindahkan keyboard satu kali saat sedang ditampilkan. Terima kasih.
Ken
2
alih-alih memindahkan tampilan, pindahkan textView
ericgu
1
Ini akan tetap minus nilai y tampilan jika pengguna mengganti bahasa input.
Jeffrey Neo
alih-alih mengubah self.view yang saya lakukan nilai self.myConstraint, ia bekerja tetapi masalahnya adalah tampilan (yang batasannya diterapkan) terus bergerak ke atas. apakah ada yang menghadapi masalah ini?
Sashi
5
Alih-alih menggunakan self.view.frame.origin.y -= 150penggunaan self.view.frame.origin.y = -150dan bukan self.view.frame.origin.y += 150penggunaan self.view.frame.origin.y = 0. Ini mencegah pandangan bergerak 150 setiap kali bidang baru disentuh.
gunwin
43

Untuk memindahkan tampilan Anda saat mengedit bidang teks coba ini, saya telah menerapkan ini,

Opsi 1: - ** ** Pembaruan dalam Swift 5.0 dan iPhone X, XR, XS dan XS Max Pindah menggunakan NotificationCenter

  • Daftarkan Notifikasi ini di func viewWillAppear(_ animated: Bool)

  • Daftarkan Notifikasi ini di func viewWillDisappear(_ animated: Bool)

Catatan: - Jika Anda tidak akan membatalkan pendaftaran daripada panggilan dari kelas anak dan akan menyebabkan crash atau yang lain.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillShow(notification:)), name:  UIResponder.keyboardWillShowNotification, object: nil )
}
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
}

@objc func keyboardWillShow( notification: Notification) {
    if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        var newHeight: CGFloat
        let duration:TimeInterval = (notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
        if #available(iOS 11.0, *) {
            newHeight = keyboardFrame.cgRectValue.height - self.view.safeAreaInsets.bottom
        } else {
            newHeight = keyboardFrame.cgRectValue.height
        }
        let keyboardHeight = newHeight  + 10 // **10 is bottom margin of View**  and **this newHeight will be keyboard height**
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: {
                        self.view.textViewBottomConstraint.constant = keyboardHeight **//Here you can manage your view constraints for animated show**
                        self.view.layoutIfNeeded() },
                       completion: nil)
    }
}

Opsi 2: - Ini berfungsi dengan baik

func textFieldDidBeginEditing(textField: UITextField) {
        self.animateViewMoving(up: true, moveValue: 100)
}
func textFieldDidEndEditing(textField: UITextField) {
        self.animateViewMoving(up: false, moveValue: 100)
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
    var movementDuration:NSTimeInterval = 0.3
    var movement:CGFloat = ( up ? -moveValue : moveValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration )
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}

Saya mendapat jawaban ini dari sumber ini UITextField bergerak ke atas saat keyboard muncul di Swift

DALAM Swift 4 ---

func textFieldDidBeginEditing(_ textField: UITextField) {
        animateViewMoving(up: true, moveValue: 100)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        animateViewMoving(up: false, moveValue: 100)
    }
    func animateViewMoving (up:Bool, moveValue :CGFloat){
        let movementDuration:TimeInterval = 0.3
        let movement:CGFloat = ( up ? -moveValue : moveValue)
        UIView.beginAnimations( "animateView", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration ) 
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }
Jogendra.Com
sumber
1
@ Jogendra.Com, Terima kasih atas kerja keras Anda. Namun, ini berfungsi paling baik di iPhone 5,4 dan 6. Tapi, bagaimana cara menonaktifkannya di iPhone 6plus dan iPad (yang lebih tinggi)
Thiha Aung
Jika Anda menggunakan Opsi 1, pastikan untuk menambahkan IBOutlet kendala. Anda akan membuat batasan yang ingin Anda ubah ukurannya menggunakan Auto-layout kemudian seret dan letakkan di viewcontroller untuk membuat IBOutlet yang saya rujuk sebagai self.iboutletConstraint.constant di fungsi animate. Juga ini tidak mengatur ulang stopkontak untuk menyembunyikan keyboard, saya menanganinya dengan mengatur ulang batasan ke nilai aslinya.
Hammad Tariq
21

Saya suka kode Swift bersih. Jadi, inilah kode paling ketat yang bisa saya buat untuk memindahkan tampilan teks naik / turun dengan keyboard. Saat ini bekerja di aplikasi produksi iOS8 / 9 Swift 2.

UPDATE (Maret 2016): Saya hanya memperketat kode saya sebelumnya sebanyak mungkin. Juga, ada banyak jawaban populer di sini yang meng-hardcode tinggi keyboard dan parameter animasi. Tidak perlu untuk itu, belum lagi angka-angka dalam jawaban ini tidak selalu sejalan dengan nilai aktual yang saya lihat di 6s + iOS9 saya (tinggi keyboard 226, durasi 0,25, dan kurva animasi 7). Bagaimanapun, hampir tidak ada kode tambahan untuk mendapatkan nilai-nilai itu langsung dari sistem. Lihat di bawah.

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "animateWithKeyboard:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "animateWithKeyboard:", name: UIKeyboardWillHideNotification, object: nil)
}

func animateWithKeyboard(notification: NSNotification) {

    // Based on both Apple's docs and personal experience, 
    // I assume userInfo and its documented keys are available.
    // If you'd like, you can remove the forced unwrapping and add your own default values.

    let userInfo = notification.userInfo!
    let keyboardHeight = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
    let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double
    let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as! UInt
    let moveUp = (notification.name == UIKeyboardWillShowNotification)

    // baseContraint is your Auto Layout constraint that pins the
    // text view to the bottom of the superview.

    baseConstraint.constant = moveUp ? -keyboardHeight : 0

    let options = UIViewAnimationOptions(rawValue: curve << 16)
    UIView.animateWithDuration(duration, delay: 0, options: options,
        animations: {
            self.view.layoutIfNeeded()
        },
        completion: nil
    )

}

CATATAN: Kode ini mencakup sebagian besar komentar / kasus umum. Namun, lebih banyak kode mungkin diperlukan untuk menangani berbagai orientasi dan / atau keyboard khusus Berikut adalah artikel mendalam tentang cara bekerja dengan keyboard iOS. Jika Anda perlu menangani setiap skenario, ini dapat membantu.

scootermg
sumber
Tampaknya Swift 1.1 dan saya pikir tidak akan dikompilasi di Swift 1.2 karena digunakan asuntuk gips kekuatan. as!dapat bekerja tetapi seperti yang Anda lihat di bagian lain halaman ini saya menghindari gips paksa dan memaksa membuka diri.
Joseph Lord
Kompilasi sekarang di Swift 1.2. Dan saya menambahkan komentar pada kode re: paksa dibuka. Bersulang.
scootermg
Ups. Maksud saya Swift 2.
scootermg
Tergantung bagaimana Anda menautkannya baseConstraint, mungkin itu baseConstraint.constant = moveUp ? keyboardHeight : 0bukan baseConstraint.constant = moveUp ? -keyboardHeight : 0.
limfinity
15

Sunting : Saya merekomendasikan solusi yang lebih mudah dan bersih. Cukup ubah kelas batasan spasi bawah menjadi KeyboardLayoutConstraint . Ini akan secara otomatis memperluas ke ketinggian keyboard.


Ini adalah versi yang lebih baik dari jawaban @JosephLord.

Seperti yang diuji pada iOS 8.3 iPad Simulator, Portrait. Xcode6.3 beta4, saya menemukan jawabannya tidak bekerja ketika keyboard bersembunyi karena UIKeyboardFrameEndUserInfoKeyadalah "NSRect: {{0, 1024}, {768, 264}}";. Tingginya tidak pernah 0.

Ini kembali menggunakan tradisional UIKeyboardWillShowNotificationdan UIKeyboardWillHideNotificationuntuk lebih mengetahui kapan keyboard bersembunyi daripada mengandalkan ketinggian frame akhir. UIKeyboardWillShowNotificationjuga dikirim ketika bingkai keyboard diubah sehingga harus mencakup semua kasus penggunaan.

    // You have to set this up in storyboard first!. 
    // It's a vertical spacing constraint between view and bottom of superview.
    @IBOutlet weak var bottomSpacingConstraint: NSLayoutConstraint! 

    override func viewDidLoad() {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardNotification:"), name:UIKeyboardWillShowNotification, object: nil);
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardNotification:"), name:UIKeyboardWillHideNotification, object: nil);
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func keyboardNotification(notification: NSNotification) {

        let isShowing = notification.name == UIKeyboardWillShowNotification

        if let userInfo = notification.userInfo {
            let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
            let endFrameHeight = endFrame?.size.height ?? 0.0
            let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
            let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
            let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue
            let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
            self.bottomSpacingConstraint?.constant = isShowing ? endFrameHeight : 0.0
            UIView.animateWithDuration(duration,
                delay: NSTimeInterval(0),
                options: animationCurve,
                animations: { self.view.layoutIfNeeded() },
                completion: nil)
        }
    }
Hung
sumber
Bisakah Anda jelaskan hasil edit Anda? Saya tidak bisa membuatnya bekerja. Saya memiliki UIScrollView dengan Tombol di bagian bawah. Saya menyelesaikan kelas di batasan margin bawah di bagian bawah.
schw4ndi
@ schw4ndi dengan pandangan apa batasan bawah Anda terkait? itu harus menghubungkan bagian bawah scrollview ke bagian bawah superview scrollview itu.
Hlung
Oh terima kasih, saya punya kendala antara tombol dan scrollView
schw4ndi
9

saya bekerja dengan swift 4 dan saya menyelesaikan masalah ini tanpa menggunakan kendala tambahan bawah melihat kode saya di sini. benar-benar bekerja pada kasus saya

1) Tambahkan Pengamat Pemberitahuan dalam melakukan memuat

override func viewDidLoad() {
        super.viewDidLoad()
        setupManager()
        // Do any additional setup after loading the view.
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

2) Hapus suka Pemberitahuan Pengamat

deinit {
        NotificationCenter.default.removeObserver(self)
    }

3) Tambahkan acara keyboard / sembunyikan metode suka

 @objc func keyboardWillShow(notification: NSNotification) {
            if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
                UIView.animate(withDuration: 0.1, animations: { () -> Void in
                    self.view.frame.origin.y -= keyboardSize.height
                    self.view.layoutIfNeeded()
                })
            }
        }

@objc func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            UIView.animate(withDuration: 0.1, animations: { () -> Void in
                self.view.frame.origin.y += keyboardSize.height
                self.view.layoutIfNeeded()
            })
        }
    }

4) Tambahkan delegasi textfeild dan tambahkan touchMulai metode .usefull untuk menyembunyikan keyboard ketika menyentuh di luar textfeild di layar

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)

    }
pansora abhay
sumber
harusUIKeyboardFrameEndUserInfoKey
Mikro
1
NSNotification.Name.UIKeyboardWillShow UIResponder.keyboardWillShowNotificationUIKeyboardFrameBeginUserInfoKey UIResponder.keyboardFrameBeginUserInfoKey
Diubah
7

Ini adalah versi perbaikan dari @JosephLord dan jawaban @ Hlung. Itu bisa berlaku apakah Anda memiliki tabbar atau tidak. Dan itu akan mengembalikan tampilan yang dipindahkan oleh keyboard ke posisi semula dengan sempurna.

// You have to set this up in storyboard first!. 
// It's a vertical spacing constraint between view and bottom of superview.
@IBOutlet weak var bottomSpacingConstraint: NSLayoutConstraint! 

override func viewDidLoad() {
        super.viewDidLoad()            

        //    Receive(Get) Notification
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardNotification:", name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardNotification:", name: UIKeyboardWillHideNotification, object: nil)


        self.originalConstraint = self.keyboardHeightLayoutConstraint?.constant //for original coordinate.
}

func keyboardNotification(notification: NSNotification) {
        let isShowing = notification.name == UIKeyboardWillShowNotification

        var tabbarHeight: CGFloat = 0
        if self.tabBarController? != nil {
            tabbarHeight = self.tabBarController!.tabBar.frame.height
        }
        if let userInfo = notification.userInfo {
            let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
            let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
            let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
            let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue
            let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
            self.keyboardHeightLayoutConstraint?.constant = isShowing ? (endFrame!.size.height - tabbarHeight) : self.originalConstraint!
            UIView.animateWithDuration(duration,
                delay: NSTimeInterval(0),
                options: animationCurve,
                animations: { self.view.layoutIfNeeded() },
                completion: nil)
        }
}
Jeff Gu Kang
sumber
6

Cara termudah yang tidak memerlukan kode apa pun:

  1. Unduh KeyboardLayoutConstraint.swift dan tambahkan (seret & jatuhkan) file ke proyek Anda, jika Anda belum menggunakan kerangka animasi Spring.
  2. Di storyboard Anda, buat batasan bawah untuk objek / view / textfield, pilih kendala (klik dua kali) dan di Identity Inspector, ubah kelasnya dari NSLayoutConstraint ke KeyboardLayoutConstraint.
  3. Selesai!

Objek akan dipindahkan secara otomatis dengan keyboard, dalam sinkronisasi.

gammachill
sumber
2
Solusi bagus! Tetapi Anda membutuhkan Area Aman. Bawah sebagai item pertama pada kendala (tidak berfungsi untuk saya saat item kedua). Dan itu bekerja paling baik dengan set konstan ke 0 karena mempertahankan konstanta dan menyesuaikannya, daripada hanya memindahkannya cukup jauh untuk menampilkan bidang dan keyboard.
Mythlandia
Apakah Anda memiliki versi KeyboardLayoutConstraint swift4?
jeet.chanchawat
6

Saya membuat protokol Swift 3 untuk menangani tampilan / hilangnya keyboard

import UIKit

protocol KeyboardHandler: class {

var bottomConstraint: NSLayoutConstraint! { get set }

    func keyboardWillShow(_ notification: Notification)
    func keyboardWillHide(_ notification: Notification)
    func startObservingKeyboardChanges()
    func stopObservingKeyboardChanges()
}


extension KeyboardHandler where Self: UIViewController {

    func startObservingKeyboardChanges() {

        // NotificationCenter observers
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: nil) { [weak self] notification in
          self?.keyboardWillShow(notification)
        }

        // Deal with rotations
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil) { [weak self] notification in
          self?.keyboardWillShow(notification)
        }

        // Deal with keyboard change (emoji, numerical, etc.)
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextInputCurrentInputModeDidChange, object: nil, queue: nil) { [weak self] notification in
          self?.keyboardWillShow(notification)
        }

        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil) { [weak self] notification in
          self?.keyboardWillHide(notification)
        }
    }


    func keyboardWillShow(_ notification: Notification) {

      let verticalPadding: CGFloat = 20 // Padding between the bottom of the view and the top of the keyboard

      guard let value = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
      let keyboardHeight = value.cgRectValue.height

      // Here you could have more complex rules, like checking if the textField currently selected is actually covered by the keyboard, but that's out of this scope.
      self.bottomConstraint.constant = keyboardHeight + verticalPadding

      UIView.animate(withDuration: 0.1, animations: { () -> Void in
          self.view.layoutIfNeeded()
      })
  }


  func keyboardWillHide(_ notification: Notification) {
      self.bottomConstraint.constant = 0

      UIView.animate(withDuration: 0.1, animations: { () -> Void in
          self.view.layoutIfNeeded()
      })
  }


  func stopObservingKeyboardChanges() {
      NotificationCenter.default.removeObserver(self)
  }

}

Kemudian, untuk mengimplementasikannya dalam UIViewController, lakukan hal berikut:

  • biarkan viewController mematuhi protokol ini:

    class FormMailVC: UIViewControlle, KeyboardHandler {
  • mulai amati perubahan keyboard di viewWillAppear:

    // MARK: - View controller life cycle
    override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)
      startObservingKeyboardChanges()
    }
  • berhenti mengamati perubahan keyboard di viewWillDisappear:

    override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      stopObservingKeyboardChanges()
    }
  • buat IBOutlet untuk batasan bawah dari storyboard:

    // NSLayoutConstraints
    @IBOutlet weak var bottomConstraint: NSLayoutConstraint!

    (Saya sarankan memiliki semua UI Anda tertanam di dalam "contentView", dan menautkan ke properti ini kendala bawah dari contentView ini ke panduan tata letak bawah) Kendala bawah tampilan konten

  • ubah prioritas kendala dari batasan teratas menjadi 250 (rendah)

Kendala atas tampilan konten

Ini untuk membiarkan seluruh tampilan konten meluncur ke atas saat keyboard muncul. Prioritas harus lebih rendah daripada prioritas kendala lainnya dalam subview, termasuk prioritas memeluk konten / prioritas resistensi kompresi konten.

  • Pastikan bahwa Autolayout Anda memiliki batasan yang cukup untuk menentukan bagaimana contentView harus geser ke atas.

Anda mungkin harus menambahkan batasan "lebih besar dari sama" untuk ini: batasan "lebih besar dari sama"

Dan ini dia! Tanpa keyboard

Dengan keyboard

Frédéric Adda
sumber
Ini berfungsi jika Anda memasukkan "Relation = Equal" juga, tanpa peringatan.
Valtoni Boaventura
Jika Anda menempatkan hubungan yang setara, itu mungkin hanya berfungsi dalam situasi tertentu. Di tempat lain, Anda mungkin memiliki peringatan inkonsistensi tata letak otomatis. Itu tergantung pada tata letak Anda sendiri. Itu sebabnya saya berkata "Anda mungkin harus".
Frédéric Adda
Ok Frédéric, setuju. Merupakan solusi yang bagus!
Valtoni Boaventura
hilangimport UIKit
Mirko
6

UIViewController Ekstensi sederhana seperti itu dapat digunakan

//MARK: - Observers
extension UIViewController {

    func addObserverForNotification(notificationName: String, actionBlock: (NSNotification) -> Void) {
        NSNotificationCenter.defaultCenter().addObserverForName(notificationName, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: actionBlock)
    }

    func removeObserver(observer: AnyObject, notificationName: String) {
        NSNotificationCenter.defaultCenter().removeObserver(observer, name: notificationName, object: nil)
    }
}

//MARK: - Keyboard observers
extension UIViewController {

    typealias KeyboardHeightClosure = (CGFloat) -> ()

    func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
        willHide willHideClosure: KeyboardHeightClosure?) {
            NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillChangeFrameNotification,
                object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { [weak self](notification) in
                    if let userInfo = notification.userInfo,
                        let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue(),
                        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
                        let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt,
                        let kFrame = self?.view.convertRect(frame, fromView: nil),
                        let kBounds = self?.view.bounds {

                            let animationType = UIViewAnimationOptions(rawValue: c)
                            let kHeight = kFrame.size.height
                            UIView.animateWithDuration(duration, delay: 0, options: animationType, animations: {
                                if CGRectIntersectsRect(kBounds, kFrame) { // keyboard will be shown
                                    willShowClosure?(kHeight)
                                } else { // keyboard will be hidden
                                    willHideClosure?(kHeight)
                                }
                                }, completion: nil)
                    } else {
                            print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
                    }
            })
    }

    func removeKeyboardObserver() {
        removeObserver(self, notificationName: UIKeyboardWillChangeFrameNotification)
    }
}

Contoh penggunaan

override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        removeKeyboardObserver()
    }

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    addKeyboardChangeFrameObserver(willShow: { [weak self](height) in
        //Update constraints here
        self?.view.setNeedsUpdateConstraints()
        }, willHide: { [weak self](height) in
        //Reset constraints here
        self?.view.setNeedsUpdateConstraints()
    })
}

Solusi Swift 4

//MARK: - Observers
extension UIViewController {

  func addObserverForNotification(_ notificationName: Notification.Name, actionBlock: @escaping (Notification) -> Void) {
    NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main, using: actionBlock)
  }

  func removeObserver(_ observer: AnyObject, notificationName: Notification.Name) {
    NotificationCenter.default.removeObserver(observer, name: notificationName, object: nil)
  }
}

//MARK: - Keyboard handling
extension UIViewController {

  typealias KeyboardHeightClosure = (CGFloat) -> ()

  func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
                                      willHide willHideClosure: KeyboardHeightClosure?) {
    NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame,
                                           object: nil, queue: OperationQueue.main, using: { [weak self](notification) in
                                            if let userInfo = notification.userInfo,
                                              let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
                                              let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
                                              let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt,
                                              let kFrame = self?.view.convert(frame, from: nil),
                                              let kBounds = self?.view.bounds {

                                              let animationType = UIViewAnimationOptions(rawValue: c)
                                              let kHeight = kFrame.size.height
                                              UIView.animate(withDuration: duration, delay: 0, options: animationType, animations: {
                                                if kBounds.intersects(kFrame) { // keyboard will be shown
                                                  willShowClosure?(kHeight)
                                                } else { // keyboard will be hidden
                                                  willHideClosure?(kHeight)
                                                }
                                              }, completion: nil)
                                            } else {
                                              print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
                                            }
    })
  }

  func removeKeyboardObserver() {
    removeObserver(self, notificationName: NSNotification.Name.UIKeyboardWillChangeFrame)
  }
}

Cepat 4.2

//MARK: - Keyboard handling
extension UIViewController {

    func addObserverForNotification(_ notificationName: Notification.Name, actionBlock: @escaping (Notification) -> Void) {
        NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main, using: actionBlock)
    }

    func removeObserver(_ observer: AnyObject, notificationName: Notification.Name) {
        NotificationCenter.default.removeObserver(observer, name: notificationName, object: nil)
    }

    typealias KeyboardHeightClosure = (CGFloat) -> ()

    func removeKeyboardObserver() {
        removeObserver(self, notificationName: UIResponder.keyboardWillChangeFrameNotification)
    }

    func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?,
                                        willHide willHideClosure: KeyboardHeightClosure?) {
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillChangeFrameNotification,
                                               object: nil, queue: OperationQueue.main, using: { [weak self](notification) in
                                                if let userInfo = notification.userInfo,
                                                    let frame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
                                                    let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
                                                    let c = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt,
                                                    let kFrame = self?.view.convert(frame, from: nil),
                                                    let kBounds = self?.view.bounds {

                                                    let animationType = UIView.AnimationOptions(rawValue: c)
                                                    let kHeight = kFrame.size.height
                                                    UIView.animate(withDuration: duration, delay: 0, options: animationType, animations: {
                                                        if kBounds.intersects(kFrame) { // keyboard will be shown
                                                            willShowClosure?(kHeight)
                                                        } else { // keyboard will be hidden
                                                            willHideClosure?(kHeight)
                                                        }
                                                    }, completion: nil)
                                                } else {
                                                    print("Invalid conditions for UIKeyboardWillChangeFrameNotification")
                                                }
        })
    }
}
ale_stro
sumber
2
jauh lebih "Swift" daripada solusi lain / bekerja hebat / dapat digunakan kembali di setiap controller tanpa menulis ulang semuanya -> pasti yang terbaik di sini :)
Tib
Saya mencoba tetapi tidak ada kesempatan, apakah UIScrollView diperlukan atau apa?
erdemgc
@erdemgc apakah Anda melihat Contoh penggunaan? Yang Anda butuhkan hanyalah UIViewControlller + addKeyboardChangeFrameObserver dan kemudian jangan lupa untuk menghapusnya
ale_stro
The removeKeyboardObserver()Metode sini tidak benar-benar menghapus pengamat. Jika Anda tidak menyebutnya, Anda akan melihat Invalid conditions for UIKeyboardWillChangeFrameNotificationdi konsol dari metode add. Jika Anda memanggil ini, Anda akan melihat kesalahan yang sama, artinya pengamat tidak dihapus. Dokumentasi menyatakan "Untuk membatalkan registrasi pengamatan, Anda meneruskan objek yang dikembalikan oleh metode ini ke removeObserver(_:)." Jadi yang Anda lakukan adalah menyimpan objek yang dikembalikan oleh metode itu, lalu meneruskannya saat Anda ingin menghapus pengamat.
Huy-Anh Hoang
Sebenarnya, setelah scrollview dimuat, terikat diberi nilai dan Anda tidak dapat mendeteksi apakah keyboard akan disembunyikan jika bingkai keyboard berpotongan dengan terikat.
James Kim
5

Anda dapat menggunakan perpustakaan ini dan hanya satu baris kode di appDidFinishedLaunching dan Anda selesai ..

func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    IQKeyboardManager.sharedManager().enable = true
    return true
}

IQKeyboardManager - sesuaikan tampilan setiap kali keyboard muncul tautan - https://github.com/hackiftekhar/IQKeyboardManager

Abdul Karim
sumber
4
struct MoveKeyboard {
    static let KEYBOARD_ANIMATION_DURATION : CGFloat = 0.3
    static let MINIMUM_SCROLL_FRACTION : CGFloat = 0.2;
    static let MAXIMUM_SCROLL_FRACTION : CGFloat = 0.8;
    static let PORTRAIT_KEYBOARD_HEIGHT : CGFloat = 216;
    static let LANDSCAPE_KEYBOARD_HEIGHT : CGFloat = 162;
}


  func textFieldDidBeginEditing(textField: UITextField) {
    let textFieldRect : CGRect = self.view.window!.convertRect(textField.bounds, fromView: textField)
    let viewRect : CGRect = self.view.window!.convertRect(self.view.bounds, fromView: self.view)

    let midline : CGFloat = textFieldRect.origin.y + 0.5 * textFieldRect.size.height
    let numerator : CGFloat = midline - viewRect.origin.y - MoveKeyboard.MINIMUM_SCROLL_FRACTION * viewRect.size.height
    let denominator : CGFloat = (MoveKeyboard.MAXIMUM_SCROLL_FRACTION - MoveKeyboard.MINIMUM_SCROLL_FRACTION) * viewRect.size.height
    var heightFraction : CGFloat = numerator / denominator

    if heightFraction < 0.0 {
        heightFraction = 0.0
    } else if heightFraction > 1.0 {
        heightFraction = 1.0
    }

    let orientation : UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
    if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown) {
        animateDistance = floor(MoveKeyboard.PORTRAIT_KEYBOARD_HEIGHT * heightFraction)
    } else {
        animateDistance = floor(MoveKeyboard.LANDSCAPE_KEYBOARD_HEIGHT * heightFraction)
    }

    var viewFrame : CGRect = self.view.frame
    viewFrame.origin.y -= animateDistance

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION))

    self.view.frame = viewFrame

    UIView.commitAnimations()
}


func textFieldDidEndEditing(textField: UITextField) {
    var viewFrame : CGRect = self.view.frame
    viewFrame.origin.y += animateDistance

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)

    UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION))

    self.view.frame = viewFrame

    UIView.commitAnimations()

}

Dan Terakhir karena kami menggunakan metode delegasi

func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

refactored dari menggunakan objektif-c http://www.cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html

Solomon Ayoola
sumber
Solusi ini berhasil bagi saya, meskipun saya harus melakukan beberapa pekerjaan tambahan: menyatakan nilai var animateDistance: CGFloat!tambah saya harus menangani UIKeyboardWillHideNotification ketika pengguna menekan tombol hide keyboard.
Rhuantavan
4

Solusi lain yang tidak bergantung pada pembayaran otomatis, kendala, atau outlet apa pun. Apa yang Anda butuhkan adalah bidang Anda dalam scrollview.

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillHideNotification, object: nil)
}

func makeSpaceForKeyboard(notification: NSNotification) {
    let info = notification.userInfo!
    let keyboardHeight:CGFloat = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size.height
    let duration:Double = info[UIKeyboardAnimationDurationUserInfoKey] as! Double

    if notification.name == UIKeyboardWillShowNotification {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height - keyboardHeight
            self.view.frame = frame
        })
    } else {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height + keyboardHeight
            self.view.frame = frame
        })
    }

}
Simpa
sumber
1
Ini menunjukkan layar hitam setelah UIKeyboardWillShowNotificationdipanggil.
Sachin Kumaram
4

Ini adalah versi saya untuk solusi untuk Swift 2.2:

Daftar pertama untuk Keyboard Show / Hide Notifications

NSNotificationCenter.defaultCenter().addObserver(self,
                                                 selector: #selector(MessageThreadVC.keyboardWillShow(_:)),
                                                 name: UIKeyboardWillShowNotification,
                                                 object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
                                                 selector: #selector(MessageThreadVC.keyboardWillHide(_:)),
                                                 name: UIKeyboardWillHideNotification,
                                                 object: nil)

Kemudian dengan metode yang sesuai untuk pemberitahuan tersebut, gerakkan tampilan utama ke atas atau ke bawah

func keyboardWillShow(sender: NSNotification) {
if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
  self.view.frame.origin.y = -keyboardSize.height
  }
}

func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y = 0
}

Caranya ada di bagian "keyboardWillShow" yang menerima panggilan setiap kali "QuickType Suggestion Bar" diperluas atau diciutkan. Kemudian kami selalu mengatur koordinat y dari tampilan utama yang sama dengan nilai negatif dari total tinggi keyboard (dengan atau tanpa bagian "QuickType bar").

Pada akhirnya jangan lupa untuk menghapus pengamat

deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Pavle Mijatovic
sumber
3

Berikut ini adalah solusi sederhana, di mana bidang teks memiliki kendala yang mengikatnya ke panduan tata letak bawah. Ini hanya menambah ketinggian keyboard ke konstanta kendala.

// This constraint ties the text field to the bottom layout guide
@IBOutlet var textFieldToBottomLayoutGuideConstraint: NSLayoutConstraint!

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name:UIKeyboardWillShowNotification, object: nil);
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name:UIKeyboardWillHideNotification, object: nil);
}

func keyboardWillShow(sender: NSNotification) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.textFieldToBottomLayoutGuideConstraint?.constant += keyboardSize.height
    }
}

func keyboardWillHide(sender: NSNotification) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.textFieldToBottomLayoutGuideConstraint?.constant -= keyboardSize.height
    }
}
Echessa
sumber
3

Yah, saya pikir saya mungkin sudah terlambat tetapi saya menemukan versi sederhana dari jawaban Saqib. Saya menggunakan Autolayout dengan kendala. Saya memiliki tampilan kecil di dalam tampilan utama lain dengan bidang nama pengguna dan kata sandi. Alih-alih mengubah koordinat y tampilan, saya menyimpan nilai kendala asli dalam variabel dan mengubah konstanta kendala ke beberapa nilai dan lagi setelah keyboard ditolak, saya menyiapkan kendala ke yang asli. Dengan cara ini ia menghindari masalah jawaban Saqib, (Pandangan terus bergerak ke atas dan tidak berhenti). Di bawah ini adalah kode saya ...

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
    self.originalConstraint = self.centerYConstraint.constant
  }

  func keyboardWillShow(sender: NSNotification) {
    self.centerYConstraint.constant += 30
  }

  func keyboardWillHide(sender: NSNotification) {
    self.centerYConstraint.constant = self.originalConstraint
  }
Sashi
sumber
Di dalam metode keyboardWillShow memeriksa kondisi jika self.centerYConstraint.constant == self.originalCenterYConstraint kemudian memiliki satu baris kode di antara kondisi ini. OriginalCenterYContraint adalah nilai asli dari centerYContraint yang saya simpan di viewdidload. Ini berhasil untuk saya.
Sashi
3

Swift 4.x menjawab, menggabungkan jawaban dari @Joseph Lord dan @Isuru. bottomConstraintmewakili kendala bawah dari tampilan yang ingin Anda pindahkan.

override func viewDidLoad() {
    // Call super
    super.viewDidLoad()

    // Subscribe to keyboard notifications
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(keyboardNotification(notification:)),
                                           name: UIResponder.keyboardWillChangeFrameNotification,
                                           object: nil)        
}


deinit {
    NotificationCenter.default.removeObserver(self)
}


@objc func keyboardNotification(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        // Get keyboard frame
        let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        // Set new bottom constraint constant
        let bottomConstraintConstant = keyboardFrame.origin.y >= UIScreen.main.bounds.size.height ? 0.0 : keyboardFrame.size.height

        // Set animation properties
        let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw)

        // Animate the view you care about
        UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: {
            self.bottomConstraint.constant = bottomConstraintConstant
            self.view.layoutIfNeeded()
        }, completion: nil)
    }
}
Crashalot
sumber
2

Saya telah melakukan dengan cara berikut:

Ini berguna ketika superview bidang teks dilihat

class AdminLoginViewController: UIViewController,
UITextFieldDelegate{

    @IBOutlet weak var txtUserName: UITextField!
    @IBOutlet weak var txtUserPassword: UITextField!
    @IBOutlet weak var btnAdminLogin: UIButton!

    private var activeField : UIView?

    var param:String!
    var adminUser : Admin? = nil
    var kbHeight: CGFloat!

    override func viewDidLoad()
    {
        self.addKeyBoardObserver()
        self.addGestureForHideKeyBoard()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func addGestureForHideKeyBoard()
    {
        let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
        tapGesture.cancelsTouchesInView = false
        view.addGestureRecognizer(tapGesture)
    }

    func hideKeyboard() {
        self.view.endEditing(true)
    }

    func addKeyBoardObserver(){

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "willChangeKeyboardFrame:",
name:UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "willChangeKeyboardFrame:",
name:UIKeyboardWillHideNotification, object: nil)
    }

    func removeObserver(){
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    //MARK:- textfiled Delegate

    func textFieldShouldBeginEditing(textField: UITextField) -> Bool
    {
         activeField = textField

        return true
    }
    func textFieldShouldEndEditing(textField: UITextField) -> Bool
    {
        if activeField == textField
        {
            activeField = nil
        }

        return true
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {

        if txtUserName == textField
        {
            txtUserPassword.becomeFirstResponder()
        }
        else if (textField == txtUserPassword)
        {
            self.btnAdminLoginAction(nil)
        }
        return true;
    }

    func willChangeKeyboardFrame(aNotification : NSNotification)
    {
       if self.activeField != nil && self.activeField!.isFirstResponder()
    {
        if let keyboardSize =  (aNotification.userInfo![UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
        {
            let dy = (self.activeField?.superview?.convertRect((self.activeField?.frame)!, toView: view).origin.y)!

            let height = (self.view.frame.size.height - keyboardSize.size.height)

            if dy > height
            {
                var frame = self.view.frame

                frame.origin.y = -((dy - height) + (self.activeField?.frame.size.height)! + 20)

                self.view.frame = frame
            }
        }
    }
    else
    {
        var frame = self.view.frame
        frame.origin.y = 0
        self.view.frame = frame
    }
    } }
Krishna Gawade
sumber
2
    func registerForKeyboardNotifications(){
        //Keyboard
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWasShown), name: UIKeyboardDidShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillBeHidden), name: UIKeyboardDidHideNotification, object: nil)


    }
    func deregisterFromKeyboardNotifications(){

        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)

    }
    func keyboardWasShown(notification: NSNotification){

        let userInfo: NSDictionary = notification.userInfo!
        let keyboardInfoFrame = userInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue()

        let windowFrame:CGRect = (UIApplication.sharedApplication().keyWindow!.convertRect(self.view.frame, fromView:self.view))

        let keyboardFrame = CGRectIntersection(windowFrame, keyboardInfoFrame!)

        let coveredFrame = UIApplication.sharedApplication().keyWindow!.convertRect(keyboardFrame, toView:self.view)

        let contentInsets = UIEdgeInsetsMake(0, 0, (coveredFrame.size.height), 0.0)
        self.scrollViewInAddCase .contentInset = contentInsets;
        self.scrollViewInAddCase.scrollIndicatorInsets = contentInsets;
        self.scrollViewInAddCase.contentSize = CGSizeMake((self.scrollViewInAddCase.contentSize.width), (self.scrollViewInAddCase.contentSize.height))

    }
    /**
     this method will fire when keyboard was hidden

     - parameter notification: contains keyboard details
     */
    func keyboardWillBeHidden (notification: NSNotification) {

        self.scrollViewInAddCase.contentInset = UIEdgeInsetsZero
        self.scrollViewInAddCase.scrollIndicatorInsets = UIEdgeInsetsZero

    }
Kamalkumar.E
sumber
1
Gunakan kode di atas untuk memindahkan bidang teks di atas keyboard dengan cepat 2.2 itu akan berfungsi dengan baik. Saya harap ini akan membantu seseorang.
Kamalkumar.E
1

Saya telah melakukan dengan cara berikut:

class SignInController: UIViewController , UITextFieldDelegate {

@IBOutlet weak var scrollView: UIScrollView!

// outlet declartion
@IBOutlet weak var signInTextView: UITextField!

var kbHeight: CGFloat!

/**
*
* @method viewDidLoad
*
*/

override func viewDidLoad() {
    super.viewDidLoad()

    self.signInTextView.delegate = self

}// end viewDidLoad

/**
*
* @method viewWillAppear
*
*/

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)

}// end viewWillAppear

/**
*
* @method viewDidAppear
*
*/

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)


}// end viewDidAppear

/**
*
* @method viewWillDisappear
*
*/
override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

/**
*
* @method textFieldShouldReturn
* retun the keyboard value
*
*/

// MARK -
func textFieldShouldReturn(textField: UITextField) -> Bool {
    signInTextView.resignFirstResponder()
    return true;

}// end textFieldShouldReturn

// MARK - keyboardWillShow
func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardSize =  (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            kbHeight = keyboardSize.height
            self.animateTextField(true)
        }
    }
}// end keyboardWillShow

// MARK - keyboardWillHide
func keyboardWillHide(notification: NSNotification) {
    self.animateTextField(false)
}// end keyboardWillHide

// MARK - animateTextField
func animateTextField(up: Bool) {
    var movement = (up ? -kbHeight : kbHeight)

    UIView.animateWithDuration(0.3, animations: {
        self.view.frame = CGRectOffset(self.view.frame, 0, movement)
    })
}// end animateTextField

/**
*
* @method didReceiveMemoryWarning
*
*/

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.

}// end didReceiveMemoryWarning


}// end SignInController
Vinod Joshi
sumber
1

Jika Anda seperti saya yang telah mencoba semua solusi di atas dan masih masalah Anda belum terpecahkan, saya punya solusi hebat untuk Anda yang bekerja seperti pesona. Pertama saya ingin mengklarifikasi beberapa hal tentang beberapa solusi yang disebutkan di atas.

  1. Dalam kasus saya, IQkeyboardmanager hanya berfungsi bila tidak ada tata letak otomatis yang diterapkan pada elemen, jika diterapkan maka manajer IQkeyboard tidak akan berfungsi seperti yang kami pikirkan.
  2. Hal yang sama dengan gerakan self.view ke atas .
  3. Saya telah menulis header obyektif C dengan dukungan cepat untuk mendorong UITexfield ke atas ketika pengguna mengkliknya, memecahkan masalah keyboard yang meliputi UITextfield: https://github.com/coolvasanth/smart_keyboard .
  4. Seseorang yang memiliki tingkat menengah atau lebih tinggi dalam pengembangan aplikasi iOS dapat dengan mudah memahami repositori dan mengimplementasikannya. Semua yang terbaik
Vasanth
sumber
1

Berikut ini adalah solusi umum untuk semua Langkah TextField -

1) Buat ViewController umum yang diperluas oleh ViewControllers lainnya

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)

}
 @objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= getMoveableDistance(keyboarHeight: keyboardSize.height)
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}
deinit {
    NotificationCenter.default.removeObserver(self)
}

//get the distance to move up the main view for the focus textfiled
func getMoveableDistance(keyboarHeight : CGFloat) ->  CGFloat{
    var y:CGFloat = 0.0
    if let activeTF = getSelectedTextField(){
        var tfMaxY = activeTF.frame.maxY
        var containerView = activeTF.superview!
        while containerView.frame.maxY != self.view.frame.maxY{
            let contViewFrm = containerView.convert(activeTF.frame, to: containerView.superview)
            tfMaxY = tfMaxY + contViewFrm.minY
            containerView = containerView.superview!
        }
        let keyboardMinY = self.view.frame.height - keyboarHeight
        if tfMaxY > keyboardMinY{
            y = (tfMaxY - keyboardMinY) + 10.0
        }
    }

    return y
}

2) Buat ekstensi UIViewController dan TextField yang saat ini aktif

//get active text field

ekstensi UIViewController {func getSelectedTextField () -> UITextField? {

    let totalTextFields = getTextFieldsInView(view: self.view)

    for textField in totalTextFields{
        if textField.isFirstResponder{
            return textField
        }
    }

    return nil

}

func getTextFieldsInView(view: UIView) -> [UITextField] {

    var totalTextFields = [UITextField]()

    for subview in view.subviews as [UIView] {
        if let textField = subview as? UITextField {
            totalTextFields += [textField]
        } else {
            totalTextFields += getTextFieldsInView(view: subview)
        }
    }

    return totalTextFields
}

}

Mintu Borah
sumber
Untuk beberapa alasan, saya mengalami masalah pada fungsi keyboardWillShow, ukuran keyboard semakin salah setelah beralih keyboard pertama (toggle pertama memiliki bingkai yang benar). Saya memperbaiki ini dengan mengubahnya untuk menjaga membiarkan userInfo = notification.userInfo lain {kembali} penjaga biarkan keyboardSize = userInfo [UIResponder.keyboardFrameEndUserInfoKey] sebagai? NSValue else {return} biarkan keyboardFrame = keyboardSize.cgRectValue jika self.view.frame.origin.y == 0 self.view.frame.origin.y - = getMoveableDistance (keyboarHeight: keyboardFrame.height)}. Semoga ini bisa membantu jika seseorang mendapat masalah yang sama :)
Youstanzr
1

Sangat Sederhana dan tidak perlu kode lagi. Cukup tambahkan pod 'IQKeyboardManagerSwift'di podfile Anda, dan di AppDelegatehalaman Anda tambahkan kode di bawah ini.

import IQKeyboardManagerSwift

dan dalam didFinishLaunchingWithOptions()tipe metode

IQKeyboardManager.shared.enable = true

hanya itu saja. periksa tautan video ini untuk pemahaman yang lebih baik https://youtu.be/eOM94K1ZWN8 Semoga ini bisa membantu Anda.

Raghib Arshi
sumber
Apakah itu berfungsi untuk TextView dan bagaimana saya bisa mengubah judul untuk kunci kembali "Selesai"?
tdt kien
Goto: - "IQKeyboardManager.m" Ganti baris ini (Baris No. 968): - [textField addDoneOnKeyboardWithTarget: self action: @selector (doneAction :) shouldShowPlaceholder: _shouldShowTextFieldPlaceholder] dengan ini: - [textField addRightButtonTextText :TextText :TextText :TextText :TextText :TextText :TextTextText :TextTextText :TextTextText :TextTextText: textText]. aksi mandiri: @selector (doneAction :) shouldShowPlaceholder: _shouldShowTextFieldPlaceholder]; Dan belum mencoba untuk tampilan teks, harap ini akan membantu Anda.
Raghib Arshi
1

Kode lengkap untuk mengelola keyboard.

        override func viewWillAppear(_ animated: Bool) {
            NotificationCenter.default.addObserver(self, selector: #selector(StoryMediaVC.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(StoryMediaVC.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
        }
        override func viewWillDisappear(_ animated: Bool) {
            NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
            NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
        }
        @objc func keyboardWillShow(notification: NSNotification) {
            guard let userInfo = notification.userInfo else {return}
            guard let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {return}
            let keyboardFrame = keyboardSize.cgRectValue

            if self.view.bounds.origin.y == 0{
                self.view.bounds.origin.y += keyboardFrame.height
            }
        }


        @objc func keyboardWillHide(notification: NSNotification) {
            if self.view.bounds.origin.y != 0 {
                self.view.bounds.origin.y = 0
            }
        }
Avijit Nagare
sumber
0

Saya memodifikasi solusi @Simpa sedikit .........

override func viewDidLoad() 
{

    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("makeSpaceForKeyboard:"), name:UIKeyboardWillShowNotification, object: nil);
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("makeSpaceForKeyboard:"), name:UIKeyboardWillHideNotification, object: nil);
}

deinit{
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

var keyboardIsVisible = false
override func makeSpaceForKeyboard(notification: NSNotification) {

    let info = notification.userInfo!
    let keyboardHeight:CGFloat = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size.height
    let duration:Double = info[UIKeyboardAnimationDurationUserInfoKey] as! Double

    if notification.name == UIKeyboardWillShowNotification && keyboardIsVisible == false{

        keyboardIsVisible = true

        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height - keyboardHeight
            self.view.frame = frame
        })

    } else if keyboardIsVisible == true && notification.name == UIKeyboardWillShowNotification{

    }else {
        keyboardIsVisible = false

        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height + keyboardHeight
            self.view.frame = frame
        })
    }
}
Menjemukan
sumber
0

Tidak satu pun dari mereka yang berfungsi dan saya akhirnya menggunakan inset konten untuk meningkatkan tampilan saya ketika keyboard muncul.

catatan: Saya menggunakan UITableView

Solusi yang direferensikan @ keyboard-content-offset yang seluruhnya ditulis dalam tujuan C, solusi di bawah ini adalah Swift bersih.

Tambahkan pengamat pemberitahuan @ viewDidLoad ()

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourClass.keyboardWillBeShown), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourClass.keyboardWillBeHidden), name:UIKeyboardWillHideNotification, object: nil);

Untuk mendapatkan ukuran keyboard, pertama-tama kita mendapatkan kamus userInfo dari objek notifikasi, yang menyimpan objek tambahan apa pun yang mungkin digunakan penerima kita.

Dari kamus itu kita bisa mendapatkan objek CGRect yang menggambarkan bingkai keyboard dengan menggunakan tombol UIKeyboardFrameBeginUserInfoKey.

Terapkan inset konten untuk tampilan tabel @ metode keyboardWillBeShown,

func keyboardWillBeShown(sender: NSNotification)
{        
    // Move the table view

    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
    {
        let contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0);

        yourTableView.contentInset = contentInsets;

        yourTableView.scrollIndicatorInsets = contentInsets;
    }
}

Kembalikan metode view @ keyboardWillBeHidden

func keyboardWillBeHidden(sender: NSNotification)
{
    // Moving back the table view back to the default position

    yourTableView.contentInset = UIEdgeInsetsZero;

    yourTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

Jika Anda ingin tetap mempertimbangkan orientasi perangkat, gunakan pernyataan kondisional untuk menyesuaikan kode dengan kebutuhan Anda.

// Portrait
UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0);

// Landscape
UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0);
Vikram Ezhil
sumber
0
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func keyboardWillShow(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    }
}

func keyboardWillHide(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    }
}

masukkan deskripsi gambar di sini

Amat lucu
sumber
0

Solusi Swift 4 yang saya gunakan, memperhitungkan ukuran keyboard. Ganti serverStatusStackViewdengan pandangan apa pun yang Anda pedulikan, misalnya self.view:

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        serverStatusStackView.frame.origin.y = keyboardSize.height * 2 - serverStatusStackView.frame.height
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        serverStatusStackView.frame.origin.y += keyboardSize.height
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
DI
sumber