Jak mogę wykryć, że klawiatura jest wyświetlana i ukryta w mojej aplikacji?
ios
iphone
iphone-sdk-3.0
user198725878
źródło
źródło
Odpowiedzi:
W metodzie ViewDidLoad swojej klasy skonfigurowanej do nasłuchiwania komunikatów dotyczących klawiatury:
// Listen for keyboard appearances and disappearances [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
Następnie w metodach, które określisz (w tym przypadku
keyboardDidShow
ikeyboardDidHide
) możesz coś z tym zrobić:- (void)keyboardDidShow: (NSNotification *) notif{ // Do something here } - (void)keyboardDidHide: (NSNotification *) notif{ // Do something here }
źródło
UITextFieldDelegat
e, a następnie zaimplementujtextFieldShouldReturn:
metodę. OtrzymasztextField
właśnie wprowadzony argument jako argument, który możesz porównać z własnymi polami textField i przewinąćscrollView
, aby wyświetlić odpowiednie pole tekstowe.Może po prostu trzeba
addObserver
sięviewDidLoad
. Ale mającaddObserver
wviewWillAppear
iremoveObserver
wviewWillDisappear
zapobiega rzadkich wypadków, które się dzieje, gdy zmieniają swój pogląd.Swift 4.2
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: UIResponder.keyboardWillHideNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear), name: UIResponder.keyboardWillShowNotification, object: nil) } @objc func keyboardWillAppear() { //Do something here } @objc func keyboardWillDisappear() { //Do something here } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self) }
Swift 3 i 4
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: Notification.Name.UIKeyboardWillHide, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear), name: Notification.Name.UIKeyboardWillShow, object: nil) } @objc func keyboardWillAppear() { //Do something here } @objc func keyboardWillDisappear() { //Do something here } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self) }
Starszy Szybki
override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillAppear:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillDisappear:", name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillAppear(notification: NSNotification){ // Do something here } func keyboardWillDisappear(notification: NSNotification){ // Do something here } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().removeObserver(self) }
źródło
deinit
tego:deinit { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) }
deinit { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) }
Swift 3:
NotificationCenter.default.addObserver(self, selector: #selector(viewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(viewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil) func keyboardWillShow(_ notification: NSNotification){ // Do something here } func keyboardWillHide(_ notification: NSNotification){ // Do something here }
źródło
Swift 4:
NotificationCenter.default.addObserver( self, selector: #selector(ControllerClassName.keyboardWillShow(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ControllerClassName.keyboardWillHide(_:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
Następnie dodajemy metodę zatrzymania nasłuchiwania powiadomień, gdy kończy się żywotność obiektu: -
Then add the promised methods from above to the view controller: deinit { NotificationCenter.default.removeObserver(self) } func adjustKeyboardShow(_ open: Bool, notification: Notification) { let userInfo = notification.userInfo ?? [:] let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue let height = (keyboardFrame.height + 20) * (open ? 1 : -1) scrollView.contentInset.bottom += height scrollView.scrollIndicatorInsets.bottom += height } @objc func keyboardWillShow(_ notification: Notification) { adjustKeyboardShow(true, notification: notification) } @objc func keyboardWillHide(_ notification: Notification) { adjustKeyboardShow(false, notification: notification) }
źródło
+=
Wydaje się uczynić Wstawki uzyskać większe.UIResponder.keyboardWillShowNotification
iUIResponder.keyboardWillHideNotification
, a klawisz informacyjny na klawiaturze toUIResponder.keyboardFrameBeginUserInfoKey
.Szybki - 4
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) addKeyBoardListener() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self) //remove observer } func addKeyBoardListener() { 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); } @objc func keyboardWillShow(_ notification: Notification) { } @objc func keyboardWillHide(_ notification: Notification) { }
źródło
W Swift 4.2 nazwy powiadomień zostały przeniesione do innej przestrzeni nazw. Więc teraz jest
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) addKeyboardListeners() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self) } func addKeyboardListeners() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) } @objc private extension WhateverTheClassNameIs { func keyboardWillShow(_ notification: Notification) { // Do something here. } func keyboardWillHide(_ notification: Notification) { // Do something here. } }
źródło
Szybki 5
Powyższe odpowiedzi są poprawne. Chociaż wolałbym utworzyć pomocnika, aby zakończyć
notification's observers
.Korzyść:
Przykładowy kod:
extension KeyboardHelper { enum Animation { case keyboardWillShow case keyboardWillHide } typealias HandleBlock = (_ animation: Animation, _ keyboardFrame: CGRect, _ duration: TimeInterval) -> Void } final class KeyboardHelper { private let handleBlock: HandleBlock init(handleBlock: @escaping HandleBlock) { self.handleBlock = handleBlock setupNotification() } deinit { NotificationCenter.default.removeObserver(self) } private func setupNotification() { _ = NotificationCenter.default .addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { [weak self] notification in self?.handle(animation: .keyboardWillShow, notification: notification) } _ = NotificationCenter.default .addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { [weak self] notification in self?.handle(animation: .keyboardWillHide, notification: notification) } } private func handle(animation: Animation, notification: Notification) { guard let userInfo = notification.userInfo, let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue, let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return } handleBlock(animation, keyboardFrame, duration) } }
Jak używać:
private var keyboardHelper: KeyboardHelper? ... override func viewDidLoad() { ... keyboardHelper = KeyboardHelper { [unowned self] animation, keyboardFrame, duration in switch animation { case .keyboardWillShow: print("keyboard will show") case .keyboardWillHide: print("keyboard will hide") } }
}
źródło
Zapoznaj się z sekcją Zarządzanie klawiaturą „Podręcznika programowania tekstu, sieci i edycji”, aby uzyskać informacje o śledzeniu wyświetlanej lub ukrytej klawiatury oraz o tym, jak ją wyświetlić / zamknąć.
źródło
Będziesz chciał zarejestrować się na 2 powiadomienia z klawiatury:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
Świetny post o tym, jak dostosować swoje TextField do klawiatury - http://iosdevelopertips.com/user-interface/adjust-textfield-hidden-by-keyboard.html
źródło
Swift 4 -
dd 20 october 2017
override func viewDidLoad() { [..] NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: Notification.Name.UIKeyboardWillHide, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil) } @objc func keyboardWillAppear(_ notification: NSNotification) { if let userInfo = notification.userInfo, let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue).cgRectValue { let inset = keyboardFrame.height // if scrollView is not aligned to bottom of screen, subtract offset scrollView.contentInset.bottom = inset scrollView.scrollIndicatorInsets.bottom = inset } } @objc func keyboardWillDisappear(_ notification: NSNotification) { scrollView.contentInset.bottom = 0 scrollView.scrollIndicatorInsets.bottom = 0 } deinit { NotificationCenter.default.removeObserver(self) }
źródło
Jeśli masz więcej niż jeden
UITextField
i musisz coś zrobić, gdy (lub wcześniej) klawiatura pojawia się lub znika, możesz zastosować to podejście.Dodaj
UITextFieldDelegate
do swojej klasy. Przypisz licznik całkowity, powiedzmy:NSInteger editCounter;
Ustaw ten licznik na zero gdzieś w
viewDidLoad
. Następnie zaimplementujtextFieldShouldBeginEditing
itextFieldShouldEndEditing
deleguj metody.W pierwszym dodaj 1 do editCounter. Jeśli wartość editCounter wynosi 1 - oznacza to, że pojawi się klawiatura (w przypadku, gdy zwrócisz TAK). Jeśli editCounter> 1 - oznacza to, że klawiatura jest już widoczna i inny UITextField utrzymuje fokus.
W
textFieldShouldEndEditing
odejmij 1 od editCounter. Jeśli uzyskasz zero - klawiatura zostanie odrzucona, w przeciwnym razie pozostanie na ekranie.źródło
Możesz użyć biblioteki KBKeyboardObserver . Zawiera kilka przykładów i zapewnia prosty interfejs.
źródło
Istnieje CocoaPods, aby ułatwić obserwację
NSNotificationCentr
widoczności klawiatury tutaj: https://github.com/levantAJ/Keyhipod 'Keyhi'
źródło
Więc ach, to jest teraz prawdziwa odpowiedź.
import Combine class MrEnvironmentObject { /// Bind into yr SwiftUI views @Published public var isKeyboardShowing: Bool = false /// Keep 'em from deallocatin' var subscribers: [AnyCancellable]? = nil /// Adds certain Combine subscribers that will handle updating the /// `isKeyboardShowing` property /// /// - Parameter host: the UIHostingController of your views. func setupSubscribers<V: View>( host: inout UIHostingController<V> ) { subscribers = [ NotificationCenter .default .publisher(for: UIResponder.keyboardWillShowNotification) .sink { [weak self] _ in self?.isKeyboardShowing = true }, NotificationCenter .default .publisher(for: UIResponder.keyboardWillHideNotification) .sink { [weak self, weak host] _ in self?.isKeyboardShowing = false // Hidden gem, ask me how I know: UIAccessibility.post( notification: .layoutChanged, argument: host ) }, // ... Profit .sink { [weak self] profit in profit() }, ] } }
źródło