Jak programowo sprawdzić, czy klawiatura jest obecna w aplikacji na iOS?

111

Muszę sprawdzić stan widoczności klawiatury w mojej aplikacji na iOS.

Pseudo kod:

if(keyboardIsPresentOnWindow) {
    //Do action 1
}
else if (keyboardIsNotPresentOnWindow) {
    //Do action 2
}

Jak mogę sprawdzić ten stan?

Jitendra Singh
źródło
Jaka aplikacja? Jaki język? Jaka platforma? Moje najlepsze przypuszczenie to iPhone?
Nick Bedford,
4
Pytanie naprawione. Niech rozpocznie się gra!
Robert Harvey
Być może to
Peter Wong

Odpowiedzi:

68

… Lub na łatwiznę:

Po wprowadzeniu pola textField staje się ono pierwszą osobą odpowiadającą i pojawia się klawiatura. Możesz sprawdzić stan klawiatury za pomocą [myTextField isFirstResponder]. Jeśli powróci YES, klawiatura jest aktywna.

thpitsch
źródło
21
Dobre rozwiązanie, jednak to NIE zadziała, jeśli używana jest klawiatura sprzętowa (nie jest to niezwykłe na iPadzie).
Andrei Herford,
4
To nie odpowiada na pytanie. Dzięki temu dowiesz się, czy pole tekstowe jest pierwszą osobą odpowiadającą. Mam kontroler widoku z wieloma kontrolerami widoku podrzędnego, z których wszystkie zawierają UITextFields. Korzystając z tej metody, nie mogę stwierdzić z mojego nadrzędnego kontrolera widoku, czy klawiatura jest wyświetlana. Jedynym niezawodnym sposobem jest użycie metody powiadamiania opisanej w innych odpowiedziach
TimWhiting
63

Kod drawonward jest bardzo zbliżony, ale koliduje z przestrzenią nazw UIKit i może być łatwiejszy w użyciu.

@interface KeyboardStateListener : NSObject {
    BOOL _isVisible;
}
+ (KeyboardStateListener *)sharedInstance;
@property (nonatomic, readonly, getter=isVisible) BOOL visible;
@end

static KeyboardStateListener *sharedInstance;

@implementation KeyboardStateListener

+ (KeyboardStateListener *)sharedInstance
{
    return sharedInstance;
}

+ (void)load
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    sharedInstance = [[self alloc] init];
    [pool release];
}

- (BOOL)isVisible
{
    return _isVisible;
}

- (void)didShow
{
    _isVisible = YES;
}

- (void)didHide
{
    _isVisible = NO;
}

- (id)init
{
    if ((self = [super init])) {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(didShow) name:UIKeyboardDidShowNotification object:nil];
        [center addObserver:self selector:@selector(didHide) name:UIKeyboardWillHideNotification object:nil];
    }
    return self;
}

@end
rpetrich
źródło
4
Dlaczego potrzebuje własnego basenu?
Dan Rosenstark
18
+loadto specjalna metoda wywoływana przez środowisko wykonawcze Objective-C. Jest wywoływana dla każdej klasy po załadowaniu pliku binarnego aplikacji, ale przed wprowadzeniem main()funkcji. Nie ma gwarancji, że pula autowydzielania będzie dostępna.
rpetrich
1
MattDiPasquale: Jeśli metoda + load zostanie usunięta, sharedInstance nigdy nie zostanie zainicjowane. Ponieważ nie ma gwarancji, że pula autorelease jest aktywna, gdy środowisko wykonawcze wywołuje metodę + load, zawijanie wszystkich wywołań do klas dostarczonych przez system jest konieczne w przypadku wywołania autorelease.
rpetrich
3
Niezła odpowiedź! Wiem, że to kilka lat, ale NSAutoreleasePool alloc/ releasemoże być teraz zastąpiona przez otaczający kod@autoreleasepool { }
chown
3
Nie zapomnij usunąć Observera, prawdopodobnie w dealloc dla KeyboardStateListener.
SushiGrass Jacob
32

Utwórz, UIKeyboardListenergdy wiesz, że klawiatura nie jest widoczna, na przykład dzwoniąc [UIKeyboardListener shared]z applicationDidFinishLaunching.

@implementation UIKeyboardListener

+ (UIKeyboardListener) shared {
    static UIKeyboardListener sListener;    
    if ( nil == sListener ) sListener = [[UIKeyboardListener alloc] init];

    return sListener;
}

-(id) init {
    self = [super init];

    if ( self ) {
        NSNotificationCenter        *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(noticeShowKeyboard:) name:UIKeyboardDidShowNotification object:nil];
        [center addObserver:self selector:@selector(noticeHideKeyboard:) name:UIKeyboardWillHideNotification object:nil];
    }

    return self;
}

-(void) noticeShowKeyboard:(NSNotification *)inNotification {
    _visible = true;
}

-(void) noticeHideKeyboard:(NSNotification *)inNotification {
    _visible = false;
}

-(BOOL) isVisible {
    return _visible;
}

@end
KlimczakM
źródło
Uwaga: Możesz użyć +(void)loaddo wywołania init w tej klasie nasłuchiwania, aby generalnie działał jako przeciągnij i upuść do dowolnego projektu i zainicjował z drugiego uruchomienia aplikacji, zamiast pamiętać o zainicjowaniu go w dowolnym miejscu.
Albert Renshaw
30

Myślę, że musisz skorzystać z powiadomień, które są dostarczane na temat klawiatury:

Od: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITextField_Class/Reference/UITextField.html

Powiadomienia z klawiatury

Gdy system pokazuje lub ukrywa klawiaturę, wysyła kilka powiadomień z klawiatury. Te powiadomienia zawierają informacje o klawiaturze, w tym o jej rozmiarze, których można używać do obliczeń obejmujących przenoszenie widoków. Rejestracja w celu otrzymywania tych powiadomień to jedyny sposób na uzyskanie niektórych informacji o klawiaturze. System dostarcza następujące powiadomienia o zdarzeniach związanych z klawiaturą:

* UIKeyboardWillShowNotification
* UIKeyboardDidShowNotification
* UIKeyboardWillHideNotification
* UIKeyboardDidHideNotification

Aby uzyskać więcej informacji na temat tych powiadomień, zobacz ich opisy w odwołaniu do klasy UIWindow. Aby uzyskać informacje o tym, jak wyświetlać i ukrywać klawiaturę, zobacz Tekst i Internet.

żebrze
źródło
Sprawdziłem te powiadomienia, ale nie wiem, jak je sprawdzić. Gdybyś mógł opublikować jakiś przykład, byłby to bardzo pomocny.
Jitendra Singh
2
Zajrzyj do NSNotificationCenter. Będziesz musiał zarejestrować się, aby otrzymywać powiadomienia, które Cię interesują. Nie zapomnij wyrejestrować się po zamknięciu aplikacji.
Thomas Müller,
13

Wdrożenie Swift 3

    import Foundation
class KeyboardStateListener: NSObject
{
    static let shared = KeyboardStateListener()
    var isVisible = false

    func start() {
        NotificationCenter.default.addObserver(self, selector: #selector(didShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(didHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func didShow()
    {
        isVisible = true
    }

    func didHide()
    {
        isVisible = false
    } 
}
Christos Chadjikyriacou
źródło
1
Zalecam usunięcie obserwatora w deinit lub jeśli jego kontroler widoku zniknie
Juan Boero
3
Nie ma sensu w użyciu deinit jeśli to jest pojedyncza, ponieważ nigdy nie zostanie deinited
Sirens
11

Używanie hierarchii widoku podrzędnego okna jako wskazania do wyświetlania klawiatury to hack. Jeśli Apple zmieni ich podstawową implementację, wszystkie te odpowiedzi się zepsują.

Prawidłowym sposobem byłoby monitorowanie klawiatury, pokazywanie i ukrywanie aplikacji powiadomień w całej aplikacji, na przykład w delegacie aplikacji:

W AppDelegate.h:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (assign, nonatomic) BOOL keyboardIsShowing;

@end

W AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Monitor keyboard status application wide
    self.keyboardIsShowing = NO;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

    return YES;
}

- (void)keyboardWillShow:(NSNotification*)aNotification
{
    self.keyboardIsShowing = YES;
}

- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.keyboardIsShowing = NO;
}

Następnie możesz sprawdzić za pomocą:

BOOL keyboardIsShowing = ((AppDelegate*)[UIApplication sharedApplication].delegate).keyboardIsShowing;

Należy zauważyć, że powiadomienia pokazywania / ukrywania klawiatury nie będą uruchamiane, gdy użytkownik korzysta z bluetooth lub klawiatury zewnętrznej.

Vlad
źródło
10

Dodaj rozszerzenie

extension UIApplication {
    /// Checks if view hierarchy of application contains `UIRemoteKeyboardWindow` if it does, keyboard is presented
    var isKeyboardPresented: Bool {
        if let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow"),
            self.windows.contains(where: { $0.isKind(of: keyboardWindowClass) }) {
            return true
        } else {
            return false
        }
    }
}

Następnie sprawdź, czy klawiatura jest obecna,

if UIApplication.shared.isKeyboardPresented {
     print("Keyboard presented")
} else { 
     print("Keyboard is not presented")
}
Kay Cee
źródło
Potrafiguard let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow") else { return false }; return UIApplication.shared.windows.contains(where: { $0.isKind(of: keyboardWindowClass) })
Clay Bridges
5

Pochodzi z podręcznika programowania tekstowego iOS opublikowanego przez Apple tutaj: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

Zasadniczo wywołaj „registerForKeyBoardNotifications” w swoim ViewDidLoad. Następnie za każdym razem, gdy klawiatura staje się aktywna, wywoływana jest funkcja „keyboardWasShown”. Za każdym razem, gdy klawiatura znika, wywoływana jest funkcja „keyboardWillBeHidden”.

// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
    NSLog(@"Keyboard is active.");
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification {
    NSLog(@"Keyboard is hidden");
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}
Właz
źródło
5

Teraz w iOS8 to rozwiązanie oczywiście nie działa. Został napisany początkowo dla IOS4 / 5.

Wypróbuj to rozwiązanie:

- (BOOL) isKeyboardOnScreen 
{
    BOOL isKeyboardShown = NO;

    NSArray *windows = [UIApplication sharedApplication].windows;
    if (windows.count > 1) {
        NSArray *wSubviews =  [windows[1]  subviews];
        if (wSubviews.count) {
            CGRect keyboardFrame = [wSubviews[0] frame];
            CGRect screenFrame = [windows[1] frame];
            if (keyboardFrame.origin.y+keyboardFrame.size.height == screenFrame.size.height) {
                isKeyboardShown = YES;
            }
        }
    }

    return isKeyboardShown;
}
malex
źródło
2
Nieprawidłowe jest założenie, że wiele okien oznacza klawiaturę, a klawiatura zawsze jest drugim elementem.
jmah
1
@jmah Oczywiście nie jest to podejście uniwersalne, ale obejmuje ogromną liczbę przypadków aplikacji. Każda próba uzyskania informacji o klawiaturze używa określonej hierarchii widoków, ponieważ Apple nie zapewnia żadnego przydatnego interfejsu API w tym przypadku.
malex
To nie działa, co zadziałało dla mnie, to iteracja przez wszystkie widoki i dla wszystkich UITextFields lub UITextView sprawdź, czy są pierwszymi respondentami ... jeśli któraś z nich zwraca prawdziwą klawiaturę, w przeciwnym razie nie
amd
4

Kilka uwag:

Zalecany wzorzec dla pojedynczego obiektu byłby następujący. dispatch_once zapewnia, że ​​klasa jest inicjowana raz w sposób bezpieczny dla wątków, a zmienna statyczna nie jest widoczna na zewnątrz. Jest to standardowe GCD, więc nie trzeba znać szczegółów niskiego poziomu Objective-C.

+ (KeyboardStateListener *)sharedInstance
{
    static KeyboardStateListener* shared;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[KeyboardStateListener alloc] init];
        // Other initialisations
    });

    return shared;
}

Zwykle nie chcesz wiedzieć, czy klawiatura jest widoczna, czy nie, ale jaka jest. Nie wszystkie klawiatury mają ten sam rozmiar. Klawiatury iPhone'a są mniejsze niż klawiatury iPada. Więc chciałbyś mieć inną właściwość, @property (readonly, nonatomic) CGRect keyboardRect;która jest ustawiona w metodzie noticeShowKeyboard: jak ta:

NSValue* value = notification.userInfo [UIKeyboardFrameEndUserInfoKey];
_keyboardRect = value.CGRectValue;

Należy zauważyć, że prostokąt ma współrzędne UIWindow i nie uwzględnia obrotu ekranu. Więc dzwoniący konwertuje ten prostokąt, wywołując

KeyboardStateListener* listener = [KeyboardStateListener sharedInstance];
CGRect windowRect = listener.keyboardRect;
CGRect viewRect = [myView convertRect:windowRect fromView:self.window];

Jeśli użytkownik obróci ekran, gdy klawiatura jest widoczna, aplikacja zostanie poinformowana, że ​​klawiatura jest ukryta, a następnie zostanie wyświetlona ponownie. Gdy jest wyświetlany, najprawdopodobniej inne widoki nie są jeszcze obracane. Jeśli więc sam obserwujesz zdarzenia ukrywania / pokazywania klawiatury, przekonwertuj współrzędne, gdy faktycznie ich potrzebujesz, a nie w powiadomieniu.

Jeśli użytkownik podzieli lub oddokuje klawiaturę albo użyje klawiatury sprzętowej, w powiadomieniach będzie zawsze wyświetlana klawiatura jako ukryta. Oddokowanie lub połączenie klawiatury spowoduje wysłanie powiadomienia „wyświetlono klawiaturę”.

Odbiornik musi zostać zainicjowany, gdy klawiatura jest ukryta, w przeciwnym razie pierwsze powiadomienie zostanie pominięte i zostanie przyjęte, że klawiatura jest ukryta, gdy nie jest.

Dlatego bardzo ważne jest, aby wiedzieć, czego naprawdę chcesz. Ten kod jest przydatny, aby usunąć elementy z drogi klawiatury (w przypadku klawiatury podzielonej lub niezadokowanej, za to odpowiada użytkownik). Nie informuje, czy użytkownik widzi klawiaturę na ekranie (w przypadku klawiatury podzielonej). Nie informuje, czy użytkownik może pisać (na przykład, gdy jest klawiatura sprzętowa). Przeglądanie innych okien nie działa, jeśli aplikacja sama tworzy inne okna.

Chris
źródło
Dobre ostrzeżenia o klawiaturze w iPadzie, dzięki!
JOM
3

Szybka realizacja:

class KeyboardStateListener: NSObject
{
  static var shared = KeyboardStateListener()
  var isVisible = false

  func start() {
    let nc = NSNotificationCenter.defaultCenter()
    nc.addObserver(self, selector: #selector(didShow), name: UIKeyboardDidShowNotification, object: nil)
    nc.addObserver(self, selector: #selector(didHide), name: UIKeyboardDidHideNotification, object: nil)
  }

  func didShow()
  {
    isVisible = true
  }

  func didHide()
  {
    isVisible = false
  } 
}

Ponieważ swift nie wykonuje metody ładowania klas podczas uruchamiania, ważne jest, aby uruchomić tę usługę podczas uruchamiania aplikacji:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
  ...    
  KeyboardStateListener.shared.start() 
}
Prcela
źródło
Używając iOS 13, swift 5.0 w tym ostatnim fragmencie, ładowanie klasy nie wydaje się konieczne?
user3069232
3

To jest moje rozwiązanie, zawiera wszystko w jednej statycznej metodzie i możesz ją wywołać w dowolnym miejscu, aby sprawdzić:

+(BOOL)isKeyboardVisible{
    static id tokenKeyboardWillShow = nil;
    static id tokenKeyboardWillHide = nil;
    static BOOL isKbVisible = NO;
    @synchronized (self) {
        if (tokenKeyboardWillShow == nil){
            tokenKeyboardWillShow = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
                @synchronized (self) {
                    isKbVisible = YES;
                }
            }];
        }

        if (tokenKeyboardWillHide == nil){
            tokenKeyboardWillHide = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
                @synchronized (self) {
                    isKbVisible = NO;
                }
            }];
        }
    }

    return isKbVisible;
}
pthr
źródło
2

A oto jak to zrobić w Swift:

 func registerForKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "keyboardWasShown:",
        name: UIKeyboardDidShowNotification,
        object: nil)

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "keyboardWillBeHidden:",
        name: UIKeyboardWillHideNotification,
        object: nil)
}

func keyboardWasShown(notification: NSNotification) {
    println("Keyboard was shown");
}

func keyboardWillBeHidden(notification: NSNotification) {
    println("Keyboard was dismissed");
}

Nie zapomnij wyrejestrować się:

 override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self,
        name: UIKeyboardDidShowNotification,
        object: nil)

    NSNotificationCenter.defaultCenter().removeObserver(self,
        name: UIKeyboardWillHideNotification,
        object: nil)
}

A jeśli chcesz zamknąć klawiaturę po naciśnięciu przycisku „Return”:

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var yourTextField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    registerForKeyboardNotifications()
    yourTextField.delegate = self
}

func textFieldShouldReturn(textField: UITextField!) -> Bool {
    self.view.endEditing(true);
    return false;
}

}
Teodor Ciuraru
źródło
1

Wypróbuj tę funkcję

BOOL UIKeyboardIsVisible(){

BOOL keyboardVisible=NO;
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
    if (![[testWindow class] isEqual:[UIWindow class]]) {
        keyboardWindow = testWindow;
        break;
    }
}
// Locate UIKeyboard.
for (UIView *possibleKeyboard in [keyboardWindow subviews]) {
    // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
    if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) {
        keyboardVisible=YES;
    }
    if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) {
        keyboardVisible=YES;
        break;
    }
}
return keyboardVisible;

}

from: iOS: Jak uzyskać dostęp do `UIKeyboard`?

Vanguarder
źródło
1

BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. Jeśli zwraca TAK, klawiatura jest aktywna.

Hardik Mamtora
źródło
1

Aby sprawdzić, czy pojawiła się klawiatura pogodowa, możemy skorzystać z powiadomień predefiniowanych Klawiatura.

UIKeyboardDidShowNotification, UIKeyboardDidHideNotification

Na przykład mogę użyć następującego kodu, aby odsłuchać powiadomienie z klawiatury

// Nasłuchuj pojawiania się i znikania klawiatury

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

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

w metodach mogę otrzymywać powiadomienia

- (void)keyboardDidShow: (NSNotification *) notifyKeyBoardShow{
    // key board is closed
}

- (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{
    // key board is opened
}
Manoj Singhal
źródło
1

Szybki 4

extension UIViewController {
    func registerKeyboardNotifications() {
        let center = NotificationCenter.default
        center.addObserver(self, selector: #selector(keyboardWillBeShown(note:)), name: Notification.Name.UIKeyboardWillShow, object: nil)
        center.addObserver(self, selector: #selector(keyboardWillBeHidden(note:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
    }

    func removeKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)

    }

    @objc
    func keyboardWillBeShown(note: Notification) {}

    @objc
    func keyboardWillBeHidden(note: Notification) {}

}

final class MyViewController: UIViewController {

    // MARK: - Properties
    var isKeyboardVisible = false

    // MARK: - Life Cycle
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        registerKeyboardNotifications()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        removeKeyboardNotifications()
    }

    // MARK: - Keyboard Handling
    override func keyboardWillBeShown(note: Notification) {
        isKeyboardVisible = true
        let userInfo = note.userInfo
        let keyboardFrame = userInfo?[UIKeyboardFrameEndUserInfoKey] as! CGRect
        let contentInset = UIEdgeInsetsMake(0.0, 0.0, keyboardFrame.height, 0.0)
        tableView.contentInset = contentInset
    }

   override func keyboardWillBeHidden(note: Notification) {
        tableView.contentInset = .zero
        isKeyboardVisible = false
   }

   // MARK: - Test
   fileprivate func test() {
        if isKeyboardVisible { // do something
        }
   }
}
Bursztyn K
źródło
U mnie działa bardzo dobrze (Xcode 10.2, Swift4) tylko ciekawy, dlaczego nikt na to nie zagłosował?
infinity_coding7
Nie, to nie działa, jeśli klawiatura była już prezentowana przez poprzedni kontroler widoku.
Ricardo
0

Możesz iteracyjnie sprawdzić wszystkie widoki tekstu, pola tekstowe i etykiety w widokach podrzędnych widoku nadrzędnego, aby zobaczyć, czy któryś z nich jest pierwszym respondentem z czymś takim:

-(BOOL)isKeyboardActiveInView:(UIView *)view {
    for (UIView *anyView in [view subviews]) {
        if ([anyView isKindOfClass:[UITextField class]]) {
            if (((UITextField *)anyView).isFirstResponder) {
                return YES;
            }
        } else if ([anyView isKindOfClass:[UILabel class]]) {
            if (((UILabel *)anyView).isFirstResponder) {
                return YES;
            }
        } else if ([anyView isKindOfClass:[UITextView class]]) {
            if (((UITextView *)anyView).isFirstResponder) {
                return YES;
            }
        } else {
            if ([self isKeyboardActiveInView:anyView]) {
                return YES;
            }
        }
    }
    return NO;
}
Albert Renshaw
źródło
To się nie powiedzie, jeśli masz kontrolery widoku podrzędnego
Ricardo
-1

SWIFT 4.2 / SWIFT 5

class Listener {
   public static let shared = Listener()
   var isVisible = false

   // Start this listener if you want to present the toast above the keyboard.
   public func startKeyboardListener() {
      NotificationCenter.default.addObserver(self, selector: #selector(didShow), name: UIResponder.keyboardWillShowNotification, object: nil)
      NotificationCenter.default.addObserver(self, selector: #selector(didHide), name: UIResponder.keyboardWillHideNotification, object: nil)
   }

   @objc func didShow() {
     isVisible = true
   }

    @objc func didHide(){
       isVisible = false
    }
}
Amrit Sidhu
źródło
-5

Myślę, że to może ci pomóc,

+(BOOL)isKeyBoardInDisplay  {

    BOOL isExists = NO;
    for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows])   {
        if ([[keyboardWindow description] hasPrefix:@"<UITextEffectsWindow"] == YES) {
            isExists = YES;
        }  
    }

    return isExists;
}

dzięki,

Naveen Shan

Naveen Shan
źródło
1
Na iOS 6 Tylko prace jeszcze się nie pojawiły! Raz pokazana klawiatura przestaje działać.
James Laurenstin