Klavye gösterilip gizlendiğinde nasıl tespit edilir


Yanıtlar:


168

Sınıfınızın ViewDidLoad yönteminde, klavye hakkındaki mesajları dinleyecek şekilde ayarlayın:

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

Daha sonra belirlediğiniz yöntemlerde (bu durumda keyboardDidShowve keyboardDidHide) bununla ilgili bir şeyler yapabilirsiniz:

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

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

Alanlar arasında sekme yaparsanız çalışmaz. Bunun için çözümün ne olacağını ve gerçek bir iPad'de bile sekme yapıp yapamayacağınızı merak ediyor musunuz?
ben--

@apprentice Klavyenin sekmenizde görünmediğini mi söylüyorsunuz?
Matthew Frederick

Odaklanılan alanın altında hala klavye tarafından kapsanan alanlar varsa, yalnızca klavye yukarı kaydığı anda
i

3
@apprentice Bunu, klavyenin ne zaman göründüğünü bilmekten farklı bir problem olan, her metin alanının etkin hale gelmesine bağlı olarak kaydırma görünümünü kaydırarak elle yönetmelisiniz. Görünüm denetleyicinizi a UITextFieldDelegate yapın, ardından textFieldShouldReturn:yöntemi uygulayın. Yeni textFieldgirileni, kendi textFields'ınızla karşılaştırabileceğiniz scrollViewve uygun textField'in gösterilmesi için kaydırabileceğiniz bir bağımsız değişken olarak alacaksınız .
Matthew Frederick

95

Sadece gerekebilir addObserveriçinde viewDidLoad. Ama sahip addObserveriçinde viewWillAppearve removeObserverde viewWillDisappearsizin görünümü değişiyor ne olur önler nadir çöker.

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

Hızlı 3 ve 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)
}

Eski 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
Gözlemcinizi viewWillDisappear'da kaldırırsanız ... onu viewDidLoad yerine viewWillAppear'a eklemelisiniz.
FouZ

Bu doğru, cevabı düzenlemekten çekinmeyin. Kabul edeceğim
Esqarrouth

@FouZ gelen gözlemciler kaldırmak için daha iyi olduğunu deinitböyle:deinit { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) }
Crashalot

Swift 3'te, yukarıdaki tanımlı kod bloğu şöyledir: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, siz vc'yi kapatana kadar çalışmaz. bu yüzden bunun üzerine başka bir vc sunarsanız, bildirimleri almaya devam edecektir. Amacın yalnızca bu vc görünür durumdayken bu bildirimleri dinlemek olduğuna inanıyorum, bu yüzden bunu viewdidappear'a eklemek ve viewdiddissapear'da kaldırmak bana daha iyi geliyor.
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)

Ardından, nesnenin ömrü sona erdiğinde bildirimleri dinlemeyi durduracak yöntem eklemek: -

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

+=İnsets daha büyük ve daha büyük olsun yapmak görünür.
Wez

AdjustKeyboardShow işlevinin çok iyi yapılmış bir işlev olduğunu düşünüyorum. Teşekkür ederim.
hong geliştiricisi

Swift olarak 5 bildirim adıdır UIResponder.keyboardWillShowNotificationve UIResponder.keyboardWillHideNotificationve klavye bilgisi anahtarıdır UIResponder.keyboardFrameBeginUserInfoKey.
CodeBrew

7

Swift 5

Yukarıdaki cevaplar doğrudur. Her ne kadar ben bir yardımcı oluşturmayı tercih etsem de notification's observers.

Fayda:

  1. Klavye davranışlarını her işlediğinizde tekrar etmeniz gerekmez.
  2. Diğer enum değerini uygulayarak diğer bildirimleri genişletebilirsiniz.
  3. Birkaç denetleyicide klavye ile uğraşmanız gerektiğinde kullanışlıdır.

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

Nasıl kullanılır:

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

}


5

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

}

5

Swift 4.2'de bildirim adları farklı bir ad alanına taşındı. Yani şimdi

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

4

Check out Klavye yönetme bölümüne "Metin, Web, ve Düzenleme Kılavuzu Programlama", görünür veya gizli olan klavye izleme konusunda bilgi ve nasıl el ile görevden / gösterilecek.


4

2 klavye bildirimine kaydolmak isteyeceksiniz:

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

TextField'inizi klavyeye nasıl ayarlayacağınızla ilgili harika gönderi - http://iosdevelopertips.com/user-interface/adjust-textfield-hidden-by-keyboard.html


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

Birden fazla s'niz varsa UITextFieldve klavye göründüğünde (veya daha önce) bir şeyler yapmanız gerekiyorsa, bu yaklaşımı uygulayabilirsiniz.

UITextFieldDelegateSınıfınıza ekleyin . Tam sayı sayacı atayın, diyelim ki:

NSInteger editCounter; 

Bu sayacı içinde bir yerde sıfıra ayarlayın viewDidLoad. Ardından, yöntemleri uygulayın textFieldShouldBeginEditingve textFieldShouldEndEditingyetkilendirin.

İlkinde editCounter'a 1 ekleyin. EditCounter değeri 1 olursa - bu, klavyenin görüneceği anlamına gelir (EVET döndürmeniz durumunda). EditCounter> 1 ise - bu, klavyenin zaten görünür olduğu ve odağı başka bir UITextField'ın tuttuğu anlamına gelir.

Gelen textFieldShouldEndEditingeditCounter Çıkart 1. Sıfır alırsanız - klavye kapatılacaktır, aksi takdirde ekranda kalacaktır.




0

Yani ah, şimdi gerçek cevap bu.

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() },
        ]
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.