So erkennen Sie, wann die Tastatur angezeigt und ausgeblendet wird


Antworten:


166

In der ViewDidLoad-Methode Ihrer Klasse können Sie Nachrichten über die Tastatur abhören:

// 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];

Dann können Sie in den von Ihnen angegebenen Methoden (in diesem Fall keyboardDidShowund keyboardDidHide) etwas dagegen tun:

- (void)keyboardDidShow: (NSNotification *) notif{
    // Do something here
}

- (void)keyboardDidHide: (NSNotification *) notif{
    // Do something here
}

Funktioniert nicht, wenn Sie durch Felder tippen. Fragen Sie sich, was die Lösung dafür wäre und ob Sie sogar auf einem tatsächlichen iPad durchblättern können?
10.

@apprentice Meinst du, dass die Tastatur nicht angezeigt wird, wenn Sie eine Registerkarte verwenden?
Matthew Frederick

Wenn noch Felder unterhalb des
Fokusfelds

3
@apprentice Sie müssen dies von Hand verwalten, indem Sie die Bildlaufansicht je nach aktivem Textfeld verschieben. Dies ist ein anderes Problem als das Wissen, wann die Tastatur angezeigt wird. Machen Sie Ihren View Controller zu einem UITextFieldDelegate und implementieren Sie die textFieldShouldReturn:Methode. Sie erhalten das textFieldgerade eingegebene Argument, das Sie mit Ihren eigenen Textfeldern vergleichen und durch das Bild scrollen können, scrollViewsodass das entsprechende Textfeld angezeigt wird.
Matthew Frederick

94

Möglicherweise brauchen Sie nur addObserverin viewDidLoad. Aber mitaddObserver in viewWillAppearundremoveObserver inviewWillDisappear verhindern seltene Abstürze , die passieren , wenn Sie die Ansicht verändern.

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

Älterer Swift

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

9
Wenn Sie Ihren Beobachter in viewWillDisappear ... entfernen, sollten Sie ihn in viewWillAppear anstelle von viewDidLoad hinzufügen.
FouZ

Das ist wahr, zögern Sie nicht, die Antwort zu bearbeiten. Ich werde es akzeptieren
Esqarrouth

@FouZ ist es besser, die Beobachter deinitwie folgt zu entfernen :deinit { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) }
Crashalot

In Swift 3 ist der obige Deinit-Codeblock wie folgt:deinit { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) }
Md. Najmul Hasan

@Crashalot das deinit läuft erst, wenn du den vc entlässt. Wenn Sie also einen anderen VC über diesen präsentieren, erhält dieser weiterhin die Benachrichtigungen. Ich glaube, der Zweck ist es, diese Benachrichtigungen nur anzuhören, während diese VC sichtbar ist. Daher erscheint es mir besser, sie auf viewdidappear hinzuzufügen und auf viewdiddissapear zu entfernen.
Pochi

19

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
}

9

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)

Als nächstes fügen Sie eine Methode hinzu, um das Abhören von Benachrichtigungen zu beenden, wenn die Lebensdauer des Objekts endet: -

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

Das +=scheint die Einsätze immer größer zu machen.
Wez

Ich denke, die Funktion adjustKeyboardShow ist eine sehr gut gemachte Funktion. Danke dir.
Hong Entwickler

Ab Swift 5 lautet der Benachrichtigungsname UIResponder.keyboardWillShowNotificationund UIResponder.keyboardWillHideNotification, und die Tastaturinfo-Taste lautet UIResponder.keyboardFrameBeginUserInfoKey.
CodeBrew

5

Schnell - 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) {

}

4

Schauen Sie sich die Verwaltung der Tastatur Abschnitt der „Text, Web und Bearbeiten von Programmierhandbuch“ für Informationen über die Verfolgung der Tastatur angezeigt oder ausgeblendet wird, und wie zur Anzeige / abzuweisen manuell.


4

Sie möchten sich für die 2 Tastaturbenachrichtigungen registrieren:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];

Großartiger Beitrag zum Anpassen Ihres TextField an die Tastatur - http://iosdevelopertips.com/user-interface/adjust-textfield-hidden-by-keyboard.html


4

In Swift 4.2 wurden die Benachrichtigungsnamen in einen anderen Namespace verschoben. So, jetzt ist es

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

3

Swift 5

Die obigen Antworten sind richtig. Obwohl ich es vorziehen würde, einen Helfer zu erstellen, um das zu erledigennotification's observers .

Der Vorteil:

  1. Sie müssen nicht jedes Mal wiederholen, wenn Sie mit dem Tastaturverhalten umgehen.
  2. Sie können andere Benachrichtigungen erweitern, indem Sie einen anderen Aufzählungswert implementieren
  3. Dies ist nützlich, wenn Sie mit der Tastatur in mehreren Controllern arbeiten müssen.

Beispielcode:

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

Wie benutzt man:

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

}}


2

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

1

Wenn Sie mehr als eine haben UITextFieldund etwas tun müssen, wenn (oder vorher) die Tastatur erscheint oder verschwindet, können Sie diesen Ansatz implementieren.

Fügen Sie UITextFieldDelegateIhrer Klasse hinzu. Weisen Sie einen ganzzahligen Zähler zu, sagen wir:

NSInteger editCounter; 

Setzen Sie diesen Zähler irgendwo in auf Null viewDidLoad. Implementieren textFieldShouldBeginEditingund textFieldShouldEndEditingdelegieren Sie dann Methoden.

Im ersten addiere 1 zu editCounter. Wenn der Wert von editCounter 1 wird, bedeutet dies, dass die Tastatur angezeigt wird (falls Sie JA zurückgeben). Wenn editCounter> 1 - bedeutet dies, dass die Tastatur bereits sichtbar ist und ein anderes UITextField den Fokus behält.

In textFieldShouldEndEditingsubtrahieren Sie 1 von editCounter. Wenn Sie Null erhalten, wird die Tastatur geschlossen, andernfalls bleibt sie auf dem Bildschirm.




0

Also ah, das ist jetzt die wahre Antwort.

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() },
        ]
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.