Как написать уведомления клавиатуры в Swift 3

Я пытаюсь обновить этот код до Swift 3:

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

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

До сих пор я только пробовал автоматические исправления, предоставленные компилятором. В результате получается такой код:

let notificationCenter = NotificationCenter.default()
notificationCenter.addObserver(self, selector: Selector(("keyboardWillShow:")), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

notificationCenter.addObserver(self, selector: Selector(("keyboardWillHide:")), name: NSNotification.Name.UIKeyboardWillHide, object: nil)`

К сожалению, это не уводит меня далеко, что приводит к дополнительным ошибкам.

Кто-нибудь решил это, пожалуйста?

Обратите внимание, что я просто пытаюсь написать уведомления. Я (пока) не пытаюсь исправить функции уведомлений. Спасибо.


person ICL1901    schedule 17.06.2016    source источник
comment
Возможный дубликат Swift 3 NSNotificationCenter Keyboardwillshow/hide   -  person Anish Parajuli 웃    schedule 17.06.2016
comment
Немного по-другому - упомянутый вопрос касается функций отображения/скрытия клавиатуры. Этот вопрос касается настройки уведомлений.   -  person ICL1901    schedule 17.06.2016
comment
хорошо, дайте мне знать, если это не помогло   -  person Anish Parajuli 웃    schedule 17.06.2016
comment
Спасибо, Аниш, я пока разбираюсь, как писать сами уведомления.   -  person ICL1901    schedule 17.06.2016


Ответы (9)


Свифт 4

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

func keyboardWillShow(notification: NSNotification) {
     print("keyboardWillShow")
}

func keyboardWillHide(notification: NSNotification){
     print("keyboardWillHide")
}

deinit {
     NotificationCenter.default.removeObserver(self)
}

Вы также можете получить информацию о клавиатуре, используя приведенный ниже код внутри этих методов.

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil) .      

@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
 }
person ZAFAR007    schedule 25.01.2018
comment
Спасибо! Я собирался пересмотреть свой вопрос. - person ICL1901; 25.01.2018
comment
Лучше использовать UIKeyboardDidShow, а не UIKeyboardWillShow, или это одно и то же? - person Michael Hsu; 06.05.2018
comment
@MichaelHsu Это зависит от тебя. Если вам нужно вызвать функцию до появления клавиатуры, вы можете использовать метод keyboardWillShow, в противном случае вы можете использовать UIKeyboardDidShow, который будет вызываться после появления клавиатуры. - person ZAFAR007; 10.05.2018
comment
@MichaelHsu очень редко вы хотите использовать didShow; обычно вы хотите, чтобы ваша клавиатура избегала анимации и копировала кривую анимации и продолжительность клавиатуры. - person Dan Rosenstark; 13.05.2018
comment
Хотя это решение работает, стоит упомянуть, что вам нужно удалить наблюдатель уведомлений в viewWillDisappear, чтобы избежать утечки памяти. Просто добавьте: override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self) } - person nja; 17.09.2018

Swift 4.2 Xcode 10 (10L213o)

Основные изменения по сравнению со Swift 3 заключаются в UIWindow.keyboardWillShowNotification и UIWindow.keyboardWillHideNotification

let notifier = NotificationCenter.default
notifier.addObserver(self,
                     selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)),
                     name: UIWindow.keyboardWillShowNotification,
                     object: nil)
notifier.addObserver(self,
                     selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)),
                     name: UIWindow.keyboardWillHideNotification,
                     object: nil)


@objc
func keyboardWillShowNotification(_ notification: NSNotification) {}

@objc
func keyboardWillHideNotification(_ notification: NSNotification) {}
person fssilva    schedule 24.07.2018
comment
Вы уверены, что ввели их правильно? Оба говорят UIWindow.keyboardWillShowNotification - person ICL1901; 24.07.2018

Я исправил эту проблему, написав такой код

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
person Ben Rawner    schedule 29.09.2016

Для Swift 4.2 .UIKeyboardWillShow переименовывается в UIResponder.keyboardWillShowNotification, а .UIKeyboardWillHide переименовывается в UIResponder.keyboardWillHideNotification.

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

   @objc func NameOfSelector() {
       //Actions when notification is received
    }
person Vigneshraj Sekarbabu    schedule 16.09.2018
comment
Это сделало это для меня. Спасибо - person RJB; 08.09.2019

Вы можете заменить устаревший строковый литерал Selector парой #selector(Class.method) с проверкой типа:

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

center.addObserver(self,
                   selector: #selector(keyboardWillHide(_:)),
                   name: .UIKeyboardWillHide,
                   object: nil)

Синтаксис #selector намного безопаснее, поскольку Swift может во время компиляции проверять, что указанный метод действительно существует.

Для получения дополнительной информации о селекторах Swift см. подробный ответ Рикстера.

person Community    schedule 17.07.2016
comment
Круто, я только что использовал это! Дополнительное замечание на случай, если кто-то запустит мою проблему: при реализации keyboardWillShow и keyboardWillHide не делайте их приватными функциями, иначе у вас будет ошибка компилятора. - person Sami; 07.01.2017

Swift 5.1 + комбинированный + SwiftUI

@State var keyboardHeight: CGFloat = 0 // or @Published if one is in ViewModel: ObservableObject

private var cancellableSet: Set<AnyCancellable> = []
    
init() {
            
   let notificationCenter = NotificationCenter.default
        
   notificationCenter.publisher(for: UIWindow.keyboardWillShowNotification)
       .map {
             guard
                 let info = $0.userInfo,
                 let keyboardFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
                 else { return 0 }

             return keyboardFrame.height
         }
         .assign(to: \.keyboardHeight, on: self)
         .store(in: &cancellableSet)
        
     notificationCenter.publisher(for: UIWindow.keyboardDidHideNotification)
         .map { _ in 0 }
         .assign(to: \.keyboardHeight, on: self)
         .store(in: &cancellableSet)
    }
    
person Sergey    schedule 24.10.2019

В Swift 3.0

 override func viewDidLoad()
    {
        super.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)

}

Клавиатура показать и скрыть

func keyboardWillShow(notification: NSNotification) 
{

      // Your Code Here
}

func keyboardWillHide(notification: NSNotification)
{  
   //Your Code Here     
}
person Amul4608    schedule 19.12.2017

Вы можете выполнять уведомления с клавиатуры в обеих версиях Swift соответственно.

Добавьте наблюдательный сервер:

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

Функция вызова Swift 3

func keyboardDidShow() {
          print("keyboardDidShow")
       }

Функция вызова В Swift 4

@objc func keyboardDidShow() {
      print("keyboardDidShow")
   }
person Tech    schedule 18.12.2017
comment
Почему мы должны использовать ключевое слово @objc для работы? есть ли способ чистого быстрого кода для 4? - person Suresh Durishetti; 08.01.2018
comment
Поскольку метод keyboardDidShow вызывается из Objective C, swift 4 настаивает на том, чтобы вы добавили ключевое слово @objc перед методом вызова. - person Tech; 07.02.2018

Вот лучшее решение, которое работает для меня на данный момент (используется с канала YouTube «Давайте создадим это приложение»)

class ChatVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

// reference to your UIView with message TextField

    @IBOutlet weak var ChatView: UIView!   


// bottom constrain to your UIView (in my case ChatView)

    var bottomConstraint: NSLayoutConstraint?  

    override func viewDidLoad() {
        super.viewDidLoad()

// add some text in the placeholder if you want

        messageField.placeholder = "Type your message.." 

// here we add two notifications for showing and hiding the keyboard

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

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: UIResponder.keyboardWillHideNotification, object: nil)


// defines the start position for message textField that will be shown on the screen

        bottomConstraint = NSLayoutConstraint(item: ChatViewField!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: -40)    
        view.addConstraint(bottomConstraint!)    
    }

// handles notifications for both cases when keyboard pops up and disappears  

  @objc func handleKeyboardNotification(notification: NSNotification){
        if let userInfo = notification.userInfo {

            let keyboardFrame =  (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
            print(keyboardFrame)

            let isKeyboardShowing = notification.name == UIResponder.keyboardWillShowNotification

            bottomConstraint?.constant = isKeyboardShowing ? -keyboardFrame.height : -40

// makes animation at the same time as the keyboard

UIView.animate(withDuration: 0, delay: 0, options: UIView.AnimationOptions.curveEaseOut, animations: {

                self.view.layoutIfNeeded()
            }) { (completed) in    
            }   
        }
    }
person Ivan.I    schedule 20.11.2019