Перемістіть подання вгору лише тоді, коли клавіатура охоплює поле введення


148

Я намагаюся створити екран введення для iPhone. На екрані є ряд полів введення. Більшість з них у верхній частині екрана, але два поля внизу. Коли користувач намагається редагувати текст у нижній частині екрана, клавіатура з’явиться, і він закриє екран. Я знайшов просте рішення перемістити екран вгору, коли це відбувається, але результат полягає в тому, що екран завжди переміщується вгору, а поля вгорі екрана переміщуються недоступними, коли користувач намагається редагувати їх.

Чи є спосіб переміщення екрана лише після редагування нижніх полів?

Я використав цей код, який я знайшов тут :

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
}

Ви можете скористатися функцією textFieldDidBeginEditing (textField: UITextField!) {}, щоб визначити, яке текстове поле розпочало редагування та зробити приховування / показ клавіатури
humblePilgrim

Я забув згадати, що я новачок у Свіфті :( Який би був правильний синтаксис, щоб перевірити це? (Як я отримаю ім'я поля в цій функції?)
Джон Аллійн

Відповіді:


211

Ваша проблема добре пояснена в цьому документі Apple . Приклад коду на цій сторінці (at Listing 4-1) виконує саме те, що вам потрібно, він прокручує ваш погляд лише тоді, коли поточне редагування має знаходитись під клавіатурою. Потрібно лише помістити потрібні елементи управління у scrollViiew. Єдина проблема полягає в тому, що це Objective-C, і я думаю, вам це потрібно в Swift .. так ... це:

Оголосити змінну

var activeField: UITextField?

потім додайте ці методи

 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
}

Не забудьте оголосити свій ViewController як UITextFieldDelegateі встановити правильні делегати у своїх методах ініціалізації: ex:

self.you_text_field.delegate = self

І не забудьте зателефонувати registerForKeyboardNotificationsна viewInit та deregisterFromKeyboardNotificationsна вихід.

Редагування / оновлення: синтаксис Swift 4.2

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
}

3
Вам потрібно зателефонувати registerForKeyboardNotifications на viewDidLoad, тож ви додасте спостерігача до центру сповіщень, коли клавіатура з’явиться чи зникне з екрана. Коли це повідомлення буде запущено, будуть викликані методи клавіатуриWasShown та keyboardWillBeHidden, а потім перегляд прокрутки переміститься відповідно до розміру клавіатури. Більш детальну інформацію про NotificationCenter ви можете знайти тут: developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Nerkyator

12
Дякую, це саме те, що я шукав - рішення, яке рекомендується яблуком. Однак у моєму випадку у мене вже був вид прокрутки, який охоплювався поза зоною видимості. Цей код відключить прокрутку після того, як клавіатура буде прихована. Я видалив "self.scrollView.scrollEnabled = false", і він все ще не прокручується. Для мене працювало "self.scrollView.contentInset = UIEdgeInsetsZero;" цей єдиний рядок у події на клавіатурі
WillHide

5
Ідеальний код. Але мені потрібно використовувати UIKeyboardFrameEndUserInfoKeyзамість цього UIKeyboardFrameBeginUserInfoKey, тому що останній повертає висоту 0. І змінити кращу точку внизу, а не походження. 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) } }
Віктор Чой

3
@MaX: Це повинно працювати, але якщо ви хочете рішення Swift4, ви можете перевірити цей приклад iOS з книги Метта Нойбурга , яку я пропоную всім розробникам iOS :)
Nerkyator

1
@MaX Я не впевнений, що це виключно швидка штука 4, але, здається, відбувається те, що textField's didBeginEditingметод називається ПІСЛЯ keyboardWillShowметоду називався. Як результат, activeFieldзмінна все ще є нульовою, що означає, що автоматична прокрутка не відбувається. Моє рішення полягало в тому, щоб помістити activeField = textFieldвиклик у shouldBeginEditingметод textField . Це вирішує порядок питання дзвінків.
HirdayGupta

150

Ось Мої 2 копійки:

Ви пробували: https://github.com/hackiftekhar/IQKeyboardManager

Надзвичайно простий в установці Swift або Objective-C.

Ось як це працює:

IQKeyboardManager (Swift): - IQKeyboardManagerSwift доступний через CocoaPods, щоб встановити його, просто додайте наступний рядок у свій Podfile: (# 236)

pod 'IQKeyboardManagerSwift'

У AppDelegate.swift просто імпортуйте IQKeyboardManagerSwift рамки та включіть 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
    }
}

І це все. Легко!


17
Ідеально. Це має бути вбудовано за замовчуванням. Смішно здається, що це не так.
NathofGod

1
Це насправді смішно, його так просто здійснити і просто працює, плюс ви отримаєте простий спосіб перемикати декілька текстових полів
Хорі

переключення в кілька текстових полів не буде працювати? на клавіатурі не відображається стрілка для переміщення між текстовими полями.
Арсал

1
Це було дивовижне рішення, дякую! Щоб коректно налаштувати CocoaPods, мені знадобилося трохи попрацювати, оскільки вони були абсолютно новими для мене. Після того, як у мене було налаштовано, це було буквально 2 рядки коду, щоб здійснити це. Дуже дякую!
IcyBlueRose

5
Це не працювало для мене в Swift 4.1 IQKeyboardManager.sharedManager (). Enable = true Переключено на IQKeyboardManager.shared.enable = true
Rmalmoe

20

Я знайшов, що для мене ідеально працює:

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

Ви також можете змінити значення висоти. Видаліть "if оператор", якщо ви хочете використовувати його для всіх текстових полів.

Ви навіть можете використовувати це для всіх елементів керування, які потребують введення користувача, наприклад TextView.


5
Пряме переміщення кадру UIView - не чудове рішення. Додатково це включає в себе твердо кодовані значення, специфічні для цього випадку використання. Я б закликав людей не застосовувати подібне рішення, а натомість робити щось, що ближче до найкращих практик, як описано у прийнятій відповіді.
MobileVet

@MobileVet Зрозумів, але це те, що працює.
Tarvo Mäesepp

дивовижна окрема логіка без зміни нашого коду
Діліп Джангід

6

Чи є спосіб переміщення екрана лише після редагування нижніх полів ?

У мене була подібна проблема, і я знайшов досить просте рішення, не використовуючи scrollView, а замість цього використовуючи, якщо заяви у методах клавіатуриWillShow / Hide.

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

Це було гарним рішенням для мене, оскільки у мене було лише два текстових поля.

Зсуває весь погляд вгору: лише тоді, коли певні текстові поля (bottomText) редагуються

Зсуває весь погляд вниз: лише тоді, коли представлення не знаходиться в початковому місці


5

Просто використовуйте це розширення для переміщення будь-якого UIView, коли клавіатура представлена.

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

Потім у перегляді перегляду прив'яжіть свій погляд до клавіатури

UiView.bindToKeyboard()

Це переміщує перегляд вгору, навіть якщо воно не потрібне, і якщо текстове поле знаходиться у верхній частині огляду, воно підніметься вгору і не буде видимим. Це не гарне рішення.
Шивам Похріял

4

Чому б не реалізувати це замість UITableViewController? Клавіатура не приховуватиме жодних текстових полів, коли вони показані.


це насправді найпростіший і найміцніший спосіб. І це працює навіть із елементами управління, які використовують користувальницький InputView замість клавіатури за замовчуванням (сповіщення UIKeyboard для них не працюють)
Radu Simionescu

1
Існує проблема, з якою ви повинні бути обережними, якщо подання таблиці вбудовано (а не є "цілою сторінкою"). Для тих , хто спіткнувся на тому, що рішення пояснюється в постах , як це і це . Сподіваємось, це допомагає комусь, що має справу з "найбільш глупою проблемою у всіх Apple"!
Fattie

3

Swift 4 (** оновлено ) з розширенням **

  1. додати кнопки в один контейнер
  2. з'єднати обмеження на дні контейнера з контейнером IBOutletBtmConstrain
  3. inViewDidLoad

    self.containerDependOnKeyboardBottomConstrain = containerBtmConstrain
    self.watchForKeyboard() 
  4. додати наступне розширення

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

1
Дякую, друже. Вся справа в правильному ключі. Я використовував UIKeyboardFrameBeginUserInfoKey, а тепер використовую UIKeyboardFrameEndUserInfoKey витончено обробляє його.
Феліпе

2

Я використовую SwiftLint, у якого виникло кілька питань із форматуванням прийнятої відповіді. Конкретно:

немає місця перед товстою кишкою, немає примусового лиття, віддайте перевагу UIEdgeInset (вгорі: тощо ... замість UIEdgeInsetMake.

тому ось ці оновлення для 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
}

1

Я думаю, що ця стаття неправильна:

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

Хоча джерело ActiveField може бути вище клавіатури, maxY може не ...

Я створив би «max» точку для activeField і перевіряю, чи є це на клавіатурі Rect.


0

Ось моя версія після прочитання документації, наданої Apple і попередніх публікацій. Одне, що я помітив, - це те, що textView не обробляється, коли покривається клавіатурою. На жаль, документація Apple не буде працювати, оскільки з будь-якої причини клавіатура називається ПІСЛЯ виклику textViewDidBeginEditing. Я вирішив це, зателефонувавши в центральний метод, який перевіряє, чи відображається клавіатура І чи редагується textView або textField. Таким чином, процес запускається лише тоді, коли існують умови BOTH.

Інший момент у textViews полягає в тому, що їх висота може бути такою, що клавіатура затискає нижню частину textView і не буде коригуватися, якби вигляд був верхній лівий пункт. Отже, код, який я написав, фактично приймає на нижній-лівій точці будь-якого textView або textField посилання на екран і бачить, чи потрапляє він у координати, що посилаються на екран представленої клавіатури, що означає, що клавіатура охоплює якусь частину її.

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

Якщо ви користуєтесь контролером навігації, підклас також встановлює автоматичне налаштування подання прокрутки для вставки на значення false.

self.automaticallyAdjustsScrollViewInsets = false

Він проходить через кожний textView та textField, щоб встановити делегатів для обробки

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

Просто встановіть базовий клас на створений тут підклас для отримання результатів.

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

}

0

Дивовижні відповіді вже надані, але це інший спосіб вирішити цю ситуацію (використовуючи Swift 3x ):

Перш за все зателефонуйте на наступний метод у 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)

}

Тепер візьміть одне IBOutletз UIViewваших UIViewcontrollerподібних обмежень : (ось UIViewпідвід, UIScrollViewце означає, що ви повинні мати UIScrollViewдля всіх своїх subViews)

@IBOutlet weak var loginViewTopConstraint: NSLayoutConstraint!

І ще одна змінна, як нижче, та додайте делегата, тобто UITextFieldDelegate:

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

Після цього ось магічна частина просто вставте цей фрагмент нижче :

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
}

Тепер останній фрагмент:

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

Не забудьте призначити делегатів усім вашим UITextFieldособамUIStoryboard

Удачі!


0

Синтаксис 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()
}

це хороший метод отримати те, що ви хочете, ви можете додати умови "якщо" для певних текстових полів, але цей тип працює для всіх ... Сподіваюся, він може бути корисним для всіх


0

Перш за все оголосимо змінну для ідентифікації вашого активного UITextField.

Крок 1:-

Як як var activeTextField: UITextField?

Крок 2: - Після цього додайте ці два рядки у 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)

Крок 3: -

Тепер визначте ці два методи у вашому класі контролера.

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
}

0

для швидкого 4.2.

Це стосується будь-якої форми. Не потрібно перегляду прокрутки. не забудьте встановити делегата.

Складіть варі з uitextfield

var clickedTextField = UITextField()

У вашому перегляді завантаження

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

Знайте текстове поле, яке натиснув. ймовірно, у вас є текстові поля на всьому екрані.

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

Перевірте, чи клавіатура покриває текстове поле чи ні.

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

Поверніться, щоб закрити клавіатуру

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

ОНОВЛЕННЯ: NSNotification.Name.UIKeyboardWillShow & NSNotification.Name.UIKeyboardWillHide перейменовані на UIResponder.keyboardWillShowNotification & UIResponder.keyboardWillHideNotification відповідно.


0

Швидкий : Ви можете зробити це, перевіривши, яке текстове поле подається.

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

-1

Цей код переміщується вгору за текстовим полем, яке ви редагуєте, щоб ви могли переглянути його у Swift 3, для цього відповіді ви також повинні зробити свій погляд 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()
}

А потім у viewDidLoad:

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

Які дзвінки (зовні 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
        }
    }
}

-1

Швидкий 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
}

-1

Прийнятий прихильник майже ідеальний. Але мені потрібно використовувати UIKeyboardFrameEndUserInfoKeyзамість того, UIKeyboardFrameBeginUserInfoKey,що останні повертають висоту клавіатури 0. І змінити кращу точку внизу, а не походження.

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

-1

Swift 4 Оновлено моє рішення

з анімацією обмежень на клавіатурі показати / заховати, насолоджуватися.

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

            })

        }
    }

}

-1

Швидкий 4

Ви можете легко рухатися вгору і вниз за UITextFieldдопомогою клавіатури з анімацією

введіть тут опис зображення

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

Знову рішення, яке підштовхує погляд без потреби, навіть коли воно не потрібно. Удосконаліть свою відповідь, що вона вводить в оману
Шивам Похріял

-1

Швидкий 4.2

Моє рішення буде (вертикально) зосереджувати погляд на a, UITextFieldякщо його положення знаходиться під клавіатурою.

Крок 1: Створіть новий швидкий файл та скопіюйте вставний UIViewWithKeyboardклас.
Крок 2: Інтерфейс Builder встановив його як спеціальний клас для ваших найкращих 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
        }
    }
}

-1

Переписаний для швидкого 4.2

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

Залишилися функції

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
}

-2

"Я забув зазначити, що я новачок у Swift :( Який би був правильний синтаксис для перевірки цього? (Як я отримаю ім'я поля в цій функції?")

Гаразд . Спочатку підтвердьте протокол UITextFieldDelegate

class YourClass:UITextFieldDelegate

Потім реалізуйте функцію

func textFieldDidBeginEditing(textField: UITextField!) {

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

Слід зазначити, що правильним підходом є використання перегляду прокрутки та розміщення перегляду, який слід зміщувати вгору / вниз всередині подання прокрутки та відповідно обробляти події клавіатури


-3

Для Swift 4.2

Цей код дозволить вам контролювати момент осі Y кадру для певного розміру екрана пристрою.

PS: Цей код не буде інтелектуально переміщувати кадр на основі розташування TextField.

Створіть розширення для 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
        }
    }
}

Додати NotificationObserver на 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 ((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
            }
        }
    }
}

1
Загалом, я б сказав, що це поганий та досить дорогий підхід до використання конкретних типів пристрою та розмірів, пов’язаних із компонуванням жорсткого коду, оскільки вони постійно змінюються.
Йоган
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.