Pindahkan tampilan hanya ketika keyboard menutupi bidang input

148

Saya mencoba membangun layar input untuk iPhone. Layar memiliki sejumlah bidang input. Kebanyakan dari mereka ada di bagian atas layar, tetapi ada dua bidang di bagian bawah. Ketika pengguna mencoba mengedit teks di bagian bawah layar, keyboard akan muncul dan akan menutupi layar. Saya menemukan solusi sederhana untuk memindahkan layar ke atas ketika ini terjadi, tetapi hasilnya adalah layar selalu bergerak ke atas dan bidang di atas layar keluar dari jangkauan ketika pengguna mencoba mengeditnya.

Apakah ada cara agar layar hanya bergerak ketika bidang bawah diedit?

Saya telah menggunakan kode ini yang saya temukan di sini :

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)
}

func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}

func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 150
}
John Allijn
sumber
mungkin Anda bisa menggunakan func textFieldDidBeginEditing (textField: UITextField!) {} untuk mendeteksi textfield mana yang sudah mulai diedit dan melakukan keyboard hide / show
humblePilgrim
Saya lupa menyebutkan bahwa saya baru mengenal Swift :( Apa yang akan menjadi sintaks yang benar untuk memeriksa ini? (Bagaimana saya mendapatkan nama bidang dalam fungsi ini?)
John Allijn

Jawaban:

211

Masalah Anda dijelaskan dengan baik dalam dokumen ini oleh Apple . Contoh kode pada halaman ini (atListing 4-1 ) melakukan apa yang Anda butuhkan, itu akan menggulir tampilan Anda hanya ketika pengeditan saat ini harus di bawah keyboard. Anda hanya perlu meletakkan kontrol yang dibutuhkan di scrollViiew. Satu-satunya masalah adalah bahwa ini adalah Objective-C dan saya pikir Anda memerlukannya di Swift..so..di sini adalah:

Deklarasikan variabel

var activeField: UITextField?

lalu tambahkan metode ini

 func registerForKeyboardNotifications()
{
    //Adding notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}


func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(notification: NSNotification)
{
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.scrollEnabled = true
    var info : NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeFieldPresent = activeField
    {
        if (!CGRectContainsPoint(aRect, activeField!.frame.origin))
        {
            self.scrollView.scrollRectToVisible(activeField!.frame, animated: true)
        }
    }


}


func keyboardWillBeHidden(notification: NSNotification)
{
    //Once keyboard disappears, restore original positions
    var info : NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.scrollEnabled = false

}

func textFieldDidBeginEditing(textField: UITextField!)
{
    activeField = textField
}

func textFieldDidEndEditing(textField: UITextField!)
{
    activeField = nil
}

Pastikan untuk mendeklarasikan ViewController Anda sebagai UITextFieldDelegatedan setel delegasi yang benar dalam metode inisialisasi Anda: mis:

self.you_text_field.delegate = self

Dan ingat untuk memanggil registerForKeyboardNotificationsviewInit dan deregisterFromKeyboardNotificationskeluar.

Edit / Perbarui: Sintaks 4.2 Swift

func registerForKeyboardNotifications(){
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}

func deregisterFromKeyboardNotifications(){
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWasShown(notification: NSNotification){
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}

@objc func keyboardWillBeHidden(notification: NSNotification){
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = false
}

func textFieldDidBeginEditing(_ textField: UITextField){
    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField){
    activeField = nil
}
Nerkyator
sumber
3
Anda harus memanggil registerForKeyboardNotifications di viewDidLoad, jadi Anda akan menambahkan pengamat ke pusat notifikasi ketika keyboard muncul atau menghilang dari layar. Saat notifikasi ini menyala, metode keyboardWasShown dan keyboardWillBeHidden akan dipanggil dan kemudian scrollview akan bergerak sesuai dengan ukuran keyboard. Anda dapat menemukan informasi lebih rinci tentang NotificationCenter di sini: developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Nerkyator
12
Terima kasih, itulah tepatnya yang saya cari - solusi yang direkomendasikan apel. Namun, dalam kasus saya, saya sudah memiliki tampilan gulir yang membentang di luar area yang dapat dilihat. Kode ini akan menonaktifkan pengguliran setelah keyboard menyembunyikan. Saya menghapus "self.scrollView.scrollEnabled = false" dan itu masih tidak akan bergulir. Apa yang berhasil bagi saya adalah "self.scrollView.contentInset = UIEdgeInsetsZero;" baris tunggal ini di acara keyboardWillHide
F Yaqoob
5
Kode sempurna. Tapi saya harus menggunakan UIKeyboardFrameEndUserInfoKeybukan UIKeyboardFrameBeginUserInfoKey, karena yang terakhir mengembalikan tinggi 0. Dan mengubah titik paling tinggi ke bawah bukan asal. if let activeField = self.activeField { var point = activeField.frame.origin point.y += activeField.frame.size.height if (!aRect.contains(point)){ self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } }
Victor Choy
3
@MaX: Seharusnya berhasil, tetapi jika Anda menginginkan solusi Swift4 Anda dapat memeriksa contoh iOS ini dari buku Matt Neuburg yang saya sarankan untuk semua pengembang iOS :)
Nerkyator
1
@MaX Saya tidak yakin apakah ini hanya 4 hal yang cepat, tetapi yang tampaknya terjadi adalah bahwa textField's didBeginEditingmetode ini disebut SETELAH keyboardWillShowmetode itu dipanggil. Akibatnya, activeFieldvariabel tersebut masih nol, yang berarti tidak ada pengguliran otomatis terjadi. Solusi saya adalah dengan activeField = textFieldmenelepon metode textField shouldBeginEditing. Ini menyelesaikan masalah urutan panggilan.
HirdayGupta
150

Inilah 2 sen saya:

Sudahkah Anda mencoba: https://github.com/hackiftekhar/IQKeyboardManager

Sangat mudah untuk menginstal Swift atau Objective-C.

Di sini cara kerjanya:

IQKeyboardManager (Swift): - IQKeyboardManagerSwift tersedia melalui CocoaPods, untuk menginstalnya cukup tambahkan baris berikut ke Podfile Anda: (# 236)

pod 'IQKeyboardManagerSwift'

Di AppDelegate.swift, cukup impor kerangka kerja IQKeyboardManagerSwift dan aktifkan IQKeyboardManager.

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

    IQKeyboardManager.sharedManager().enable = true
    // For Swift 4, use this instead
    // IQKeyboardManager.shared.enable = true


    return true
    }
}

Dan itu saja. Mudah!

Tuan H
sumber
17
Sempurna. Ini harus dibangun secara default. Tampaknya konyol.
NathofGod
1
Ini sebenarnya konyol, sangat mudah diimplementasikan dan hanya berfungsi, ditambah Anda mendapatkan cara mudah untuk beralih melalui beberapa bidang teks
Khoury
beralih ke beberapa bidang teks tidak akan berfungsi? tidak ada tampilan panah pada keypad untuk bergerak di antara bidang teks.
Arsal
1
Ini solusi yang luar biasa, terima kasih! Butuh sedikit kerjaan untuk mengatur CocoaPods dengan benar, karena semua itu baru bagi saya. Setelah saya mengaturnya, itu benar-benar 2 baris kode untuk mengimplementasikan ini dan itu bekerja dengan baik langsung dari kelelawar. Terima kasih banyak!
IcyBlueRose
5
Ini tidak berhasil untuk saya di Swift 4.1 IQKeyboardManager.sharedManager (). Enable = true Telah beralih ke IQKeyboardManager.shared.enable = true
Rmalmoe
20

Yang saya temukan berfungsi sempurna bagi saya adalah ini:

func textFieldDidBeginEditing(textField: UITextField) {
    if textField == email || textField == password {
        animateViewMoving(true, moveValue: 100)
    }
}

func textFieldDidEndEditing(textField: UITextField) {
    if textField == email || textField == password {
        animateViewMoving(false, moveValue: 100)
    }
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:NSTimeInterval = 0.3
    let 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()
}

Anda juga dapat mengubah nilai ketinggian. Hapus "jika pernyataan" jika Anda ingin menggunakannya untuk semua bidang teks.

Anda bahkan dapat menggunakan ini untuk semua kontrol yang memerlukan input pengguna seperti TextView.

Edward
sumber
5
Memindahkan bingkai UIView secara langsung bukanlah solusi yang bagus. Selain itu ini termasuk nilai-nilai hardcoded yang khusus untuk kasus penggunaan ini. Saya akan mendorong orang untuk tidak menerapkan solusi seperti ini dan malah melakukan sesuatu yang lebih dekat dengan praktik terbaik seperti yang dijelaskan dalam jawaban yang diterima.
MobileVet
@ MobileVet Dipahami, tapi ini yang berhasil.
Tarvo Mäesepp
logika terpisah yang menakjubkan tanpa mengubah kode kami
Dilip Jangid
6

Apakah ada cara agar layar hanya bergerak ketika bidang bawah diedit?

Saya memiliki masalah yang sama dan menemukan solusi yang cukup mudah tanpa menggunakan scrollView, dan sebagai gantinya menggunakan pernyataan if dalam metode keyboardWillShow / Sembunyikan.

func keyboardWillShow(notification: NSNotification) {
    if bottomText.editing{
        self.view.window?.frame.origin.y = -1 * getKeyboardHeight(notification)
    }
}

func keyboardWillHide(notification: NSNotification) {
    if self.view.window?.frame.origin.y != 0 {
        self.view.window?.frame.origin.y += getKeyboardHeight(notification)
    }
}

Ini adalah solusi yang baik bagi saya karena saya hanya memiliki dua bidang teks.

Menggeser seluruh tampilan ke atas: hanya ketika bidang teks tertentu (teks bawah) diedit

Menggeser seluruh tampilan ke bawah: hanya saat tampilan tidak di lokasi asli

villejacob
sumber
5

Cukup gunakan ekstensi ini untuk memindahkan UIView saat keyboard disajikan.

extension UIView {
    func bindToKeyboard(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }

    @objc func keyboardWillChange(_ notification: NSNotification){
        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let beginningFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let endFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        let deltaY = endFrame.origin.y - beginningFrame.origin.y

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.frame.origin.y += deltaY
        }, completion: nil)
    }
}

Kemudian di viewdidload, ikat tampilan Anda ke keyboard

UiView.bindToKeyboard()
Bilal Mustafa
sumber
Ini menggerakkan tampilan ke atas meskipun tidak diperlukan dan jika bidang teks di bagian atas tampilan akan naik dan tidak akan terlihat. Ini bukan solusi yang baik.
Shivam Pokhriyal
4

Mengapa tidak menerapkan ini dalam UITableViewController saja? Keyboard tidak akan menyembunyikan bidang teks apa pun saat ditampilkan.

RJiryes
sumber
ini sebenarnya cara termudah dan paling kuat. Dan itu berfungsi bahkan dengan kontrol yang menggunakan InputView khusus alih-alih keyboard default (notifikasi UIKeyboard tidak berfungsi untuk ini)
Radu Simionescu
1
Ada masalah yang harus Anda berhati-hati, jika tampilan tabel tertanam (daripada menjadi "seluruh halaman"). Bagi siapa pun yang tersandung oleh itu, solusinya dijelaskan dalam posting seperti ini dan ini . Semoga ini membantu seseorang yang berurusan dengan "masalah paling bodoh di seluruh Apple"!
Fattie
3

Swift 4 (** diperbarui ) dengan ekstensi **

  1. tambahkan tombol dalam satu wadah
  2. hubungkan kendala bawah wadah dengan wadah IBOutletBtmConstrain
  3. inViewDidLoad

    self.containerDependOnKeyboardBottomConstrain = containerBtmConstrain
    self.watchForKeyboard() 
  4. tambahkan ekstensi berikut

    import UIKit
    
    private var xoAssociationKeyForBottomConstrainInVC: UInt8 = 0
    
    extension UIViewController {
    
        var containerDependOnKeyboardBottomConstrain :NSLayoutConstraint! {
            get {
                return objc_getAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC) as? NSLayoutConstraint
            }
            set(newValue) {
                objc_setAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            }
        }
    
        func watchForKeyboard() {
            NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWasShown(notification:)), name:UIResponder.keyboardWillShowNotification, object: nil);
            NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name:UIResponder.keyboardWillHideNotification, object: nil);
        }
    
        @objc func keyboardWasShown(notification: NSNotification) {
            let info = notification.userInfo!
            guard let keyboardFrame: CGRect = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
              return
            }
    
            UIView.animate(withDuration: 0.3, animations: { () -> Void in
                self.containerDependOnKeyboardBottomConstrain.constant = -keyboardFrame.height
                self.view.layoutIfNeeded()
            })
        }
    
        @objc func keyboardWillHide(notification: NSNotification) {
            UIView.animate(withDuration: 0.3, animations: { () -> Void in
                self.containerDependOnKeyboardBottomConstrain.constant = 0
                self.view.layoutIfNeeded()
            })
        }
    }
iluvatar_GR
sumber
1
Terima kasih kawan Ini semua tentang kunci yang tepat. Saya menggunakan UIKeyboardFrameBeginUserInfoKey dan sekarang menggunakan UIKeyboardFrameEndUserInfoKey menanganinya dengan anggun.
Felipe
2

Saya menggunakan SwiftLint, yang memiliki beberapa masalah dengan pemformatan jawaban yang diterima. Secara khusus:

tidak ada ruang sebelum titik dua, tidak ada pengecoran paksa, lebih suka UIEdgeInset (atas: dll ... daripada UIEdgeInsetMake.

jadi inilah pembaruan untuk Swift 3

func registerForKeyboardNotifications() {
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func deregisterFromKeyboardNotifications() {
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func keyboardWasShown(notification: NSNotification) {
    //Need to calculate keyboard exact size due to Apple suggestions
    scrollView?.isScrollEnabled = true
    var info = notification.userInfo!
    if let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
        let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)

        scrollView?.contentInset = contentInsets
        scrollView?.scrollIndicatorInsets = contentInsets

        var aRect: CGRect = self.view.frame
        aRect.size.height -= keyboardSize.height
        if let activeField = self.activeField {
            if !aRect.contains(activeField.frame.origin) {
                self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
            }
        }
    }
}

func keyboardWillBeHidden(notification: NSNotification) {
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    if let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
        let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize.height, right: 0.0)
        scrollView?.contentInset = contentInsets
        scrollView?.scrollIndicatorInsets = contentInsets
    }

    view.endEditing(true)
    scrollView?.isScrollEnabled = false
}

func textFieldDidBeginEditing(_ textField: UITextField) {
    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField) {
    activeField = nil
}
Joe Hoffman
sumber
1

Saya pikir klausa ini salah:

if (!CGRectContainsPoint(aRect, activeField!.frame.origin))

Meskipun asal activeField mungkin berada di atas keyboard, maxY mungkin tidak ...

Saya akan membuat titik 'max' untuk activeField dan memeriksa apakah itu ada di keyboard Rect.

zevij
sumber
0

Ini versi saya setelah membaca dokumentasi yang disediakan oleh Apple dan posting sebelumnya. Satu hal yang saya perhatikan adalah bahwa textView tidak ditangani ketika ditutupi oleh keyboard. Sayangnya, dokumentasi Apple tidak akan berfungsi karena, untuk alasan apa pun, keyboard disebut SETELAH textViewDidBeginEditing disebut. Saya menangani ini dengan memanggil metode pusat yang memeriksa apakah keyboard ditampilkan DAN jika textView atau textField sedang diedit. Dengan cara ini, proses hanya dipecat ketika kondisi KEDUA ada.

Poin lain dengan textViews adalah bahwa tingginya mungkin sedemikian rupa sehingga keyboard klip bagian bawah textView dan tidak akan menyesuaikan jika titik Kiri-Atas dari yang terlihat. Jadi, kode yang saya tulis benar-benar mengambil titik Bawah-Kiri layar-direferensikan dari textView atau textField dan melihat apakah itu jatuh dalam koordinat yang direferensikan layar dari keyboard yang disajikan menyiratkan bahwa keyboard mencakup sebagian dari itu.

let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
    if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY))) {
        // scroll textView/textField into view
    }

Jika Anda menggunakan pengontrol navigasi, subkelas ini juga mengatur penyesuaian otomatis tampilan gulir untuk inset menjadi false.

self.automaticallyAdjustsScrollViewInsets = false

Itu berjalan melalui setiap textView dan textField untuk mengatur delegasi untuk penanganan

    for view in self.view.subviews {
        if view is UITextView {
            let tv = view as! UITextView
            tv.delegate = self
        } else if view is UITextField {
            let tf = view as! UITextField
            tf.delegate = self
        }
    }

Cukup atur kelas dasar Anda ke subclass yang dibuat di sini untuk hasil.

import UIKit

class ScrollingFormViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {

var activeFieldRect: CGRect?
var keyboardRect: CGRect?
var scrollView: UIScrollView!

override func viewDidLoad() {

    self.automaticallyAdjustsScrollViewInsets = false

    super.viewDidLoad()

    // Do any additional setup after loading the view.
    self.registerForKeyboardNotifications()
    for view in self.view.subviews {
        if view is UITextView {
            let tv = view as! UITextView
            tv.delegate = self
        } else if view is UITextField {
            let tf = view as! UITextField
            tf.delegate = self
        }
    }
    scrollView = UIScrollView(frame: self.view.frame)
    scrollView.scrollEnabled = false
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false
    scrollView.addSubview(self.view)
    self.view = scrollView
}

override func viewDidLayoutSubviews() {
    scrollView.sizeToFit()
    scrollView.contentSize = scrollView.frame.size
    super.viewDidLayoutSubviews()
}

deinit {
    self.deregisterFromKeyboardNotifications()
}

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


func registerForKeyboardNotifications()
{
    //Adding notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWasShown), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWillBeHidden), name: UIKeyboardWillHideNotification, object: nil)
}


func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(notification: NSNotification)
{
    let info : NSDictionary = notification.userInfo!
    keyboardRect = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
    adjustForKeyboard()
}


func keyboardWillBeHidden(notification: NSNotification)
{
    keyboardRect = nil
    adjustForKeyboard()
}

func adjustForKeyboard() {
    if keyboardRect != nil && activeFieldRect != nil {
        let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
        if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY)))
        {
            scrollView.scrollEnabled = true
            let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardRect!.size.height, 0.0)
            scrollView.contentInset = contentInsets
            scrollView.scrollIndicatorInsets = contentInsets
            scrollView.scrollRectToVisible(activeFieldRect!, animated: true)
        }
    } else {
        let contentInsets : UIEdgeInsets = UIEdgeInsetsZero
        scrollView.contentInset = contentInsets
        scrollView.scrollIndicatorInsets = contentInsets
        scrollView.scrollEnabled = false
    }
}

func textViewDidBeginEditing(textView: UITextView) {
    activeFieldRect = textView.frame
    adjustForKeyboard()
}

func textViewDidEndEditing(textView: UITextView) {
    activeFieldRect = nil
    adjustForKeyboard()
}

func textFieldDidBeginEditing(textField: UITextField)
{
    activeFieldRect = textField.frame
    adjustForKeyboard()
}

func textFieldDidEndEditing(textField: UITextField)
{
    activeFieldRect = nil
    adjustForKeyboard()
}

}
pengguna2690492
sumber
0

Jawaban yang luar biasa sudah diberikan tetapi ini adalah cara yang berbeda untuk menghadapi situasi ini (menggunakan Swift 3x ):

Pertama-tama panggil metode berikut ini di viewWillAppear()

func registerForKeyboardNotifications() {

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWasShown), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillBeHidden), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

Sekarang mengambil salah satu IBOutletdari UIViewkendala atas 's dari Anda UIViewcontrollerseperti ini: (di sini UIViewadalah subview UIScrollViewberarti bahwa Anda harus memiliki UIScrollViewuntuk semua Anda subViews)

@IBOutlet weak var loginViewTopConstraint: NSLayoutConstraint!

Dan variabel lain seperti mengikuti dan menambahkan delegasi yaitu UITextFieldDelegate:

var activeTextField = UITextField() //This is to keep the reference of UITextField currently active

Setelah itu di sini adalah bagian ajaib cukup tempelkan cuplikan di bawah ini :

func keyboardWasShown(_ notification: Notification) {

let keyboardInfo  = notification.userInfo as NSDictionary?

//print(keyboardInfo!)

let keyboardFrameEnd: NSValue? = (keyboardInfo?.value(forKey: UIKeyboardFrameEndUserInfoKey) as? NSValue)

let keyboardFrameEndRect: CGRect? = keyboardFrameEnd?.cgRectValue


if activeTextField.frame.origin.y + activeTextField.frame.size.height + 10 > (keyboardFrameEndRect?.origin.y)! {

    UIView.animate(withDuration: 0.3, delay: 0, options: .transitionFlipFromTop, animations: {() -> Void in

        //code with animation

        //Print some stuff to know what is actually happening
        //print(self.activeTextField.frame.origin.y)
        //print(self.activeTextField.frame.size.height)
        //print(self.activeTextField.frame.size.height)

        self.loginViewTopConstraint.constant = -(self.activeTextField.frame.origin.y + self.activeTextField.frame.size.height - (keyboardFrameEndRect?.origin.y)!) - 30.0

        self.view.layoutIfNeeded()

    }, completion: {(_ finished: Bool) -> Void in
        //code for completion

    })
}
}

func keyboardWillBeHidden(_ notification: Notification) {

UIView.animate(withDuration: 0.3, animations: {() -> Void in

    self.loginViewTopConstraint.constant = self.view.frame.origin.y
    self.view.layoutIfNeeded()

})
}

//MARK: textfield delegates
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    activeTextField = textField
    return true
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {

           switch textField {
    case YOUR_TEXTFIELD_ONE:
        YOUR_TEXTFIELD_TWO.becomeFirstResponder()
        break
    case YOUR_TEXTFIELD_TWO:
        YOUR_TEXTFIELD_THREE.becomeFirstResponder()
        break
    default:
        textField.resignFirstResponder()
        break
    }
    return true
}

Sekarang cuplikan terakhir:

//Remove Keyboard Observers
override func viewWillDisappear(_ animated: Bool) {

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

Jangan lupa untuk delegasi assign ke semua Anda UITextFields diUIStoryboard

Semoga berhasil!

Anurag Sharma
sumber
0

Sintaks Swift 3:

func textFieldDidBeginEditing(_ textField: UITextField) {
    // add if for some desired textfields
        animateViewMoving(up: true, moveValue: 100)
}

func textFieldDidEndEditing(_ textField: UITextField) {
    // add if for some desired textfields
        animateViewMoving(up: false, moveValue: 100)
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
     textFieldDidEndEditing(_ textField: UITextField) {

    let movementDuration:TimeInterval = 0.5

    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()
}

ini adalah metode yang bagus untuk mendapatkan apa yang Anda inginkan, Anda dapat menambahkan kondisi "jika" untuk bidang teks tertentu tetapi jenis ini berfungsi untuk semua ... Semoga bermanfaat bagi semua orang

Atrin Noori
sumber
0

Pertama-tama deklarasikan variabel untuk mengidentifikasi UITextField aktif Anda.

Langkah 1:-

Seperti var activeTextField: UITextField ?

Langkah 2: - Setelah ini tambahkan dua baris ini di viewDidLoad.

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)

Langkah 3: -

Sekarang tentukan kedua metode ini di kelas controller Anda.

func keyboardWillShow(_ notification: NSNotification) {

    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}


func keyboardWillHide(_ notification: NSNotification) {

    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = true
}


func textFieldDidBeginEditing(_ textField: UITextField){

    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField){

    activeField = nil
}
Hemendra Singh
sumber
0

untuk swift 4.2.

Ini akan berlaku untuk segala bentuk. Tidak perlu scrollview. jangan lupa untuk mengatur delegasi.

Buat var dari uitextfield

var clickedTextField = UITextField()

Dalam pemuatan viewdid Anda

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

Ketahui bidang teks yang diklik. mungkin Anda memiliki bidang teks di seluruh layar.

func textFieldDidBeginEditing(_ textField: UITextField) {
    clickedTextField = textField
}

Periksa apakah keyboard menutupi bidang teks atau tidak.

@objc func keyboardWillShow(sender: NSNotification,_ textField : UITextField) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

        if clickedTextField.frame.origin.y > keyboardSize.origin.y {
            self.view.frame.origin.y = keyboardSize.origin.y - clickedTextField.center.y - 20
        }
    }
}

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

Kembali untuk menutup keyboard

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

UPDATE: NSNotification.Name.UIKeyboardWillShow & NSNotification.Name.UIKeyboardWillHide diubah namanya menjadi UIResponder.keyboardWillShowNotification & UIResponder.keyboardWillHideNotification masing-masing.

rupesh45
sumber
0

Swift : Anda dapat melakukan ini dengan memeriksa textField mana yang sedang disajikan.

@objc func keyboardWillShow(notification: NSNotification) {
    if self.textField.isFirstResponder == true {
        self.view.frame.origin.y -= 150
     }
}

@objc func keyboardWillHide(notification: NSNotification){
    if self.textField.isFirstResponder == true {
       self.view.frame.origin.y += 150
    }
}
ZAFAR007
sumber
-1

Kode ini bergerak ke atas bidang teks yang sedang Anda edit sehingga Anda dapat melihatnya di Swift 3 untuk jawaban ini Anda juga harus membuat tampilan Anda menjadi UITextFieldDelegate:

var moveValue: CGFloat!
var moved: Bool = false
var activeTextField = UITextField()

func textFieldDidBeginEditing(_ textField: UITextField) {
    self.activeTextField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
    if moved == true{
    self.animateViewMoving(up: false, moveValue: moveValue )
        moved = false
    }
}
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()
}

Dan kemudian di viewDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)

Panggilan mana (di luar viewDidLoad):

func keyboardWillShow(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight = keyboardSize.height
        if (view.frame.size.height-self.activeTextField.frame.origin.y) - self.activeTextField.frame.size.height < keyboardHeight{
            moveValue = keyboardHeight - ((view.frame.size.height-self.activeTextField.frame.origin.y) - self.activeTextField.frame.size.height)
            self.animateViewMoving(up: true, moveValue: moveValue )
            moved = true
        }
    }
}
joshLor
sumber
-1

Cepat 3

@IBOutlet var scrollView: UIScrollView!
@IBOutlet var edtEmail: UITextField!
@IBOutlet var bottomTextfieldConstrain: NSLayoutConstraint! // <- this guy is the constrain that connect the bottom of textField to lower object or bottom of page!

 @IBAction func edtEmailEditingDidBegin(_ sender: Any) { 
        self.bottomTextfieldConstrain.constant = 200
        let point = CGPoint(x: 0, y: 200)
        scrollView.contentOffset = point
    }

@IBAction func edtEmailEditingDidEnd(_ sender: Any) { 
    self.bottomTextfieldConstrain.constant = 50
}
Alfi
sumber
-1

Server yang diterima hampir sempurna. Tapi saya perlu menggunakan UIKeyboardFrameEndUserInfoKeybukan UIKeyboardFrameBeginUserInfoKey,karena keyborad tinggi mengembalikan 0,90. Dan mengubah titik paling tinggi ke bawah bukan asal.

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        var point = activeField.frame.origin
        point.y += activeField.frame.size.height
        if (!aRect.contains(point)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
Victor Choy
sumber
-1

Swift 4 Memperbarui solusi saya

dengan animasi kendala di acara keyboard / sembunyikan, selamat menikmati.

import Foundation
import UIKit

class PhoneController: UIViewController, UITextFieldDelegate{

    var phoneLayoutYConstraint: NSLayoutConstraint?

    override func viewDidLoad() {

        super.viewDidLoad()

        view.backgroundColor = .white

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyBoardNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyBoardNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        phoneField.delegate = self

        view.addSubview(phoneField)

        NSLayoutConstraint.activate([phoneField.heightAnchor.constraint(equalToConstant: 50),
                                     phoneField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                                     phoneField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
                                     phoneField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)])

        phoneLayoutYConstraint = NSLayoutConstraint(item: phoneField, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
        phoneLayoutYConstraint?.isActive = true

    }

    let phoneField: UITextField = {
        let text = UITextField()
        text.translatesAutoresizingMaskIntoConstraints = false
        text.keyboardType = .numberPad
        text.font = UIFont.systemFont(ofSize: 30)
        text.layer.cornerRadius = 5.0
        text.layer.masksToBounds = true
        text.layer.borderColor = UIColor.darkGray.cgColor
        text.layer.borderWidth = 2.0

        return text
    }()


    override func viewDidDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self)
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {

    }


    func textFieldDidEndEditing(_ textField: UITextField) {

    }

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


   @objc func handleKeyBoardNotification(_ notification: NSNotification) {

        if let info = notification.userInfo {

            let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
            let isKeyBoardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow

            var aRect : CGRect = self.phoneField.frame
            aRect.size.height -= keyboardSize!.height


            phoneLayoutYConstraint?.constant = isKeyBoardShowing ? -keyboardSize!.height : 0

            UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
                self.view.layoutIfNeeded()
            }, completion: { (boo) in

            })

        }
    }

}
Hattori Hanzo
sumber
-1

Cepat 4

Anda dapat dengan mudah bergerak naik dan turun UITextFielddengan keyboard dengan animasi

masukkan deskripsi gambar di sini

import UIKit

class ViewController: UIViewController {

    @IBOutlet var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.resignFirstResponder()
    }

    @objc func keyboardWillChange(notification: NSNotification) {

        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let deltaY = targetFrame.origin.y - curFrame.origin.y

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.textField.frame.origin.y+=deltaY

        },completion: nil)
    }
ZAFAR007
sumber
Sekali lagi solusi yang akan mendorong tampilan ke atas tidak perlu bahkan ketika itu tidak diperlukan. Harap tingkatkan jawaban Anda yang menyesatkan
Shivam Pokhriyal
-1

Cepat 4.2

Solusi saya akan (secara vertikal) memusatkan tampilan pada a UITextField jika posisinya di bawah keyboard.

Langkah 1: Buat file cepat baru dan UIViewWithKeyboardkelas salin-tempel .
Langkah 2: Di Interface Builder aturlah sebagai Kelas Kustom untuk yang paling top Anda UIView.

import UIKit

class UIViewWithKeyboard: UIView {
    @IBInspectable var offsetMultiplier: CGFloat = 0.75
    private var keyboardHeight = 0 as CGFloat
    private weak var activeTextField: UITextField?
    override func awakeFromNib() {
        super.awakeFromNib()
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.textDidBeginEditing),
                                               name: UITextField.textDidBeginEditingNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.keyboardWillShow),
                                               name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.keyboardWillHide),
                                               name: UIResponder.keyboardWillHideNotification, object: nil)
    }

    @objc func textDidBeginEditing(_ notification: NSNotification) {
        self.activeTextField = notification.object as? UITextField
    }

    @objc func keyboardWillShow(_ notification: Notification) {
        if let frameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            keyboardHeight = frameValue.cgRectValue.size.height
            if let textField = self.activeTextField {
                let offset = textField.frame.maxY < frame.maxY - keyboardHeight ? 0
                           : textField.frame.maxY - (frame.maxY - keyboardHeight) * offsetMultiplier
                self.setView(offset: offset)
            }
        }
    }

    @objc func keyboardWillHide(_ notification: NSNotification) {
        self.setView(offset: 0)
    }

    func setView(offset: CGFloat) {
        UIView.animate(withDuration: 0.25) {
            self.bounds.origin.y = offset
        }
    }
}
cakupan
sumber
-1

Ditulis ulang untuk swift 4.2

Di ViewDidLoad ..

 NotificationCenter.default.addObserver(self, selector: #selector(trailViewController.keyboardWasShown), name: UIResponder.keyboardWillShowNotification, object: nil)
 NotificationCenter.default.addObserver(self, selector: #selector(trailViewController.keyboardWillBeHidden), name: UIResponder.keyboardWillHideNotification, object: nil)

Funtions yang tersisa

func registerForKeyboardNotifications(){
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}

func deregisterFromKeyboardNotifications(){
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWasShown(notification: NSNotification){
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}

@objc func keyboardWillBeHidden(notification: NSNotification){
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = false
}

func textFieldDidBeginEditing(_ textField: UITextField){
    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField){
    activeField = nil
}
VarunRaj
sumber
-2

"Saya lupa menyebutkan bahwa saya baru di Swift :( Apa sintaks yang benar untuk memeriksa ini? (Bagaimana cara mendapatkan nama bidang dalam fungsi ini?)"

Baik . Pertama konfirmasikan ke protokol UITextFieldDelegate

class YourClass:UITextFieldDelegate

Kemudian implementasikan fungsinya

func textFieldDidBeginEditing(textField: UITextField!) {

    if textField == txtOne
    {
        println("TextOne")
    }
    if textField == txtTwo
    {
        println("TextTwo")
    }
}

Anda harus mencatat bahwa pendekatan yang tepat adalah dengan menggunakan tampilan gulir dan menempatkan tampilan yang harus digeser ke atas / ke bawah di dalam tampilan gulir dan menangani kejadian keyboard yang sesuai.

Pilgrim humble
sumber
-3

Untuk Swift 4.2

Kode ini akan memungkinkan Anda untuk mengontrol momen sumbu Y dari frame untuk ukuran layar perangkat tertentu.

PS: Kode ini tidak akan memindahkan frame secara cerdas berdasarkan lokasi TextField.

Buat ekstensi untuk UIDevice

extension UIDevice {
    enum ScreenType: String {
        case iPhone4_4S = "iPhone 4 or iPhone 4s"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6s, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6s Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhoneX_Xs = "iPhone X, iPhone Xs"
        case iPhoneXR = "iPhone XR"
        case iPhoneXSMax = "iPhone Xs Max"
        case unknown
    }
    var screenType: ScreenType {
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhone4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 1792:
            return .iPhoneXR
        case 2436:
            return .iPhoneX_Xs
        case 2688:
            return .iPhoneXSMax
        default:
            return .unknown
        }
    }
}

Tambahkan NotificationObserver di 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)

Pemilih

@objc func keyboardWillShow(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
        if self.view.frame.origin.y == 0 {
            switch (UIDevice.current.screenType.rawValue) {
            case (UIDevice.ScreenType.iPhones_5_5s_5c_SE.rawValue):
                self.view.frame.origin.y -= 210
            case (UIDevice.ScreenType.iPhones_6_6s_7_8.rawValue):
                self.view.frame.origin.y -= 110
            case (UIDevice.ScreenType.iPhones_6Plus_6sPlus_7Plus_8Plus.rawValue):
                self.view.frame.origin.y -= 80
            case (UIDevice.ScreenType.iPhoneX_Xs.rawValue):
                self.view.frame.origin.y -= 70
            case (UIDevice.ScreenType.iPhoneXR.rawValue):
                self.view.frame.origin.y -= 70
            case (UIDevice.ScreenType.iPhoneXSMax.rawValue):
                self.view.frame.origin.y -= 70
            default:
                self.view.frame.origin.y -= 150
            }
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
        if self.view.frame.origin.y != 0 {
            switch (UIDevice.current.screenType.rawValue) {
            case (UIDevice.ScreenType.iPhones_5_5s_5c_SE.rawValue):
                self.view.frame.origin.y += 210
            case (UIDevice.ScreenType.iPhones_6_6s_7_8.rawValue):
                self.view.frame.origin.y += 110
            case (UIDevice.ScreenType.iPhones_6Plus_6sPlus_7Plus_8Plus.rawValue):
                self.view.frame.origin.y += 80
            case (UIDevice.ScreenType.iPhoneX_Xs.rawValue):
                self.view.frame.origin.y += 70
            case (UIDevice.ScreenType.iPhoneXR.rawValue):
                self.view.frame.origin.y += 70
            case (UIDevice.ScreenType.iPhoneXSMax.rawValue):
                self.view.frame.origin.y += 70
            default:
                self.view.frame.origin.y += 150
            }
        }
    }
}
Kavin Varnan
sumber
1
Secara umum saya akan mengatakan itu adalah pendekatan yang buruk dan agak mahal untuk menggunakan tipe spesifik perangkat dan dimensi terkait tata letak hardcode karena mereka terus berubah.
Johan