Làm cách nào để tôi có thể lập trình kiểm tra xem bàn phím có trong ứng dụng iOS hay không?


111

Tôi cần kiểm tra tình trạng hiển thị bàn phím trong ứng dụng iOS của mình.

Mã giả:

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

Làm thế nào tôi có thể kiểm tra tình trạng này?


Ứng dụng gì? Ngôn ngữ nào? Nền tảng nào? Dự đoán tốt nhất của tôi là iPhone?
Nick Bedford

4
Câu hỏi đã được sửa. Hãy để cuộc chơi bắt đầu!
Robert Harvey


Câu trả lời:


68

… Hoặc làm theo cách dễ dàng:

Khi bạn nhập một Trường văn bản, Trường này sẽ trở thành phản hồi đầu tiên và bàn phím sẽ xuất hiện. Bạn có thể kiểm tra trạng thái của bàn phím với [myTextField isFirstResponder]. Nếu nó trả về YES, thì bàn phím đang hoạt động.


21
Giải pháp tốt, tuy nhiên điều này sẽ KHÔNG hoạt động, nếu bàn phím phần cứng được sử dụng (không có gì bất thường trên iPad).
Andrei Herford

4
Điều này không trả lời câu hỏi. Điều này cho bạn biết trường văn bản có phải là trường phản hồi đầu tiên hay không. Tôi có một bộ điều khiển chế độ xem với nhiều bộ điều khiển chế độ xem con, tất cả đều chứa UITextFields. Sử dụng phương pháp này, tôi không thể biết từ bộ điều khiển chế độ xem cha mẹ của mình liệu bàn phím có được hiển thị hay không. Cách đáng tin cậy duy nhất là sử dụng phương pháp thông báo được giải thích trong các câu trả lời khác
TimWhiting

63

Mã của drawnonward rất gần, nhưng va chạm với không gian tên của UIKit và có thể dễ sử dụng hơn.

@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

4
Tại sao nó cần hồ bơi riêng?
Dan Rosenstark

18
+loadlà một phương thức đặc biệt được gọi bởi Objective-C runtime. Nó được gọi cho mỗi lớp sau khi tải nhị phân ứng dụng, nhưng trước khi main()hàm được nhập. Không có gì đảm bảo rằng một nhóm tự động vui lòng sẽ hoạt động.
rpetrich

1
MattDiPasquale: Nếu phương thức + load bị xóa, sharedInstance sẽ không bao giờ được khởi tạo. Vì không có gì đảm bảo rằng nhóm autorelease sẽ hoạt động khi thời gian chạy gọi phương thức + tải, nên việc gói tất cả các lệnh gọi đến các lớp do hệ thống cung cấp là cần thiết trong trường hợp chúng gọi autorelease.
rpetrich

3
Câu trả lời hay! Tôi biết điều này đã cũ vài năm nhưng NSAutoreleasePool alloc/ releasebây giờ có thể được thay thế bằng cách bao quanh mã trong@autoreleasepool { }
chown

3
Đừng quên xóa Trình quan sát, có thể là trong dealloc của KeyboardStateListener.
SushiGrass Jacob

32

Tạo UIKeyboardListenerkhi bạn biết bàn phím không hiển thị, chẳng hạn như bằng cách gọi [UIKeyboardListener shared]từ 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

Lưu ý: Bạn có thể sử dụng +(void)loadđể gọi init trên lớp nghe này để nói chung nó sẽ hoạt động dưới dạng kéo và thả vào bất kỳ dự án nào và khởi tạo từ lần khởi chạy ứng dụng thứ hai thay vì bạn phải nhớ init nó ở bất kỳ đâu.
Albert Renshaw

30

Tôi nghĩ bạn cần sử dụng các thông báo được cung cấp về bàn phím:

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

Thông báo bàn phím

Khi hệ thống hiển thị hoặc ẩn bàn phím, nó sẽ đăng một số thông báo về bàn phím. Các thông báo này chứa thông tin về bàn phím, bao gồm cả kích thước của bàn phím, mà bạn có thể sử dụng để tính toán liên quan đến các chế độ xem di chuyển. Đăng ký các thông báo này là cách duy nhất để nhận một số loại thông tin về bàn phím. Hệ thống gửi các thông báo sau cho các sự kiện liên quan đến bàn phím:

* UIKeyboardWillShowNotification
* UIKeyboardDidShowNotification
* UIKeyboardWillHideNotification
* UIKeyboardDidHideNotification

Để biết thêm thông tin về các thông báo này, hãy xem mô tả của chúng trong Tài liệu tham khảo Lớp UIWindow. Để biết thông tin về cách hiển thị và ẩn bàn phím, hãy xem Văn bản và Web.


Tôi đã kiểm tra các thông báo này, nhưng không biết cách kiểm tra các thông báo này. Nếu bạn có thể đăng một số ví dụ, điều đó sẽ rất hữu ích.
Jitendra Singh

2
Hãy xem NSNotificationCenter. Bạn sẽ phải đăng ký các thông báo mà bạn quan tâm. Đừng quên hủy đăng ký khi ứng dụng của bạn thoát.
Thomas Müller 29/09/09

13

Triển khai 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
    } 
}

1
Tôi khuyên bạn nên loại bỏ các quan sát viên trong deinit hoặc nếu một bộ điều khiển quan điểm của mình trong quan điểm willdisappear
Juan Boero

3
Không có điểm trong việc sử dụng một deinit nếu đây là một singleton bởi vì nó sẽ không bao giờ được deinited
Sirens

11

Sử dụng hệ thống phân cấp chế độ xem phụ cửa sổ làm dấu hiệu cho việc hiển thị bàn phím là một hành vi hack. Nếu Apple thay đổi cách triển khai cơ bản của họ, tất cả những câu trả lời này sẽ bị phá vỡ.

Cách đúng sẽ là theo dõi ứng dụng hiển thị Bàn phím và ẩn thông báo, chẳng hạn như bên trong Đại biểu ứng dụng của bạn:

Trong AppDelegate.h:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (assign, nonatomic) BOOL keyboardIsShowing;

@end

Trong 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;
}

Sau đó, bạn có thể kiểm tra bằng cách sử dụng:

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

Cần lưu ý rằng các thông báo hiển thị / ẩn bàn phím sẽ không kích hoạt khi người dùng đang sử dụng bluetooth hoặc bàn phím ngoài.


10

Thêm phần mở rộng

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

Sau đó, kiểm tra xem có bàn phím hay không,

if UIApplication.shared.isKeyboardPresented {
     print("Keyboard presented")
} else { 
     print("Keyboard is not presented")
}

Có thể làmguard let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow") else { return false }; return UIApplication.shared.windows.contains(where: { $0.isKind(of: keyboardWindowClass) })
Cầu đất sét

5

Đây là từ Hướng dẫn lập trình văn bản trên iOS do Apple xuất bản tại đây: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

Về cơ bản, hãy gọi "registerForKeyBoardNotifications" trong ViewDidLoad của bạn. Sau đó, mỗi khi bàn phím hoạt động, "keyboardWasShown" sẽ được gọi. Và mỗi khi bàn phím biến mất, "keyboardWillBeHidden" được gọi.

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

5

Bây giờ trong iOS8 giải pháp này tất nhiên không hoạt động. Ban đầu nó được viết cho IOS4 / 5.

Hãy thử giải pháp này:

- (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;
}

2
Thật không hợp lệ khi cho rằng nhiều cửa sổ ngụ ý một bàn phím và bàn phím luôn là yếu tố thứ hai.
jmah

1
@jmah Tất nhiên nó không phải là cách tiếp cận phổ biến nhưng nó bao gồm một lượng lớn các trường hợp ứng dụng. Mọi cố gắng lấy thông tin về bàn phím hãy sử dụng một số phân cấp chế độ xem cụ thể vì Apple không cung cấp bất kỳ API hữu ích nào cho trường hợp này.
malex

Điều này không hoạt động, những gì làm việc cho tôi là lặp qua tất cả quan điểm và cho tất cả các kiểm tra UITextFields hoặc UITextView nếu họ là phản ứng đầu tiên ... nếu bất kỳ sau đó trở về bàn phím thực sự có thể nhìn thấy gì khác không của nó
AMD

4

Một vài nhận xét:

Mẫu đề xuất cho một đối tượng singleton sẽ như sau. disp_once đảm bảo rằng lớp được khởi tạo một lần theo cách an toàn cho luồng và biến tĩnh không hiển thị bên ngoài. Và đó là GCD tiêu chuẩn, vì vậy không cần biết về các chi tiết cấp thấp của Objective-C.

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

    return shared;
}

Thông thường, bạn không muốn chỉ biết bàn phím có hiển thị hay không, mà là nó lớn như thế nào. Không phải tất cả các bàn phím đều có cùng kích thước. Bàn phím iPhone nhỏ hơn bàn phím iPad. Vì vậy, bạn muốn có một thuộc tính khác @property (readonly, nonatomic) CGRect keyboardRect;được đặt trong phương thức notificationShowKeyboard: như sau:

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

Điều quan trọng cần lưu ý là hình chữ nhật nằm trong tọa độ UIWindow và không tôn trọng việc xoay màn hình. Vì vậy, người gọi sẽ chuyển đổi hình chữ nhật đó bằng cách gọi

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

Nếu người dùng xoay màn hình trong khi bàn phím hiển thị, ứng dụng sẽ được thông báo rằng bàn phím bị ẩn, sau đó hiển thị lại. Khi nó được hiển thị, các chế độ xem khác rất có thể vẫn chưa được xoay. Vì vậy, nếu bạn tự quan sát các sự kiện ẩn / hiện trên bàn phím, hãy chuyển đổi tọa độ khi bạn thực sự cần chúng, không phải trong thông báo.

Nếu người dùng tách hoặc tháo bàn phím hoặc sử dụng bàn phím phần cứng, các thông báo sẽ luôn hiển thị bàn phím ở dạng ẩn. Hủy bỏ hoặc hợp nhất bàn phím sẽ gửi thông báo "bàn phím được hiển thị".

Người nghe phải được khởi tạo trong khi bàn phím bị ẩn, nếu không, thông báo đầu tiên sẽ bị bỏ qua và người ta sẽ cho rằng bàn phím bị ẩn khi không có.

Vì vậy, nó là khá quan trọng để biết những gì bạn thực sự muốn. Mã này rất hữu ích để di chuyển mọi thứ ra khỏi bàn phím (với bàn phím tách hoặc không gắn, đó là trách nhiệm của người dùng). Nó không cho bạn biết liệu người dùng có thể nhìn thấy bàn phím trên màn hình hay không (trong trường hợp bàn phím bị chia đôi). Nó không cho bạn biết liệu người dùng có thể gõ hay không (ví dụ: khi có bàn phím phần cứng). Nhìn vào các cửa sổ khác sẽ không hoạt động nếu ứng dụng tự tạo các cửa sổ khác.


Cảnh báo tốt về bàn phím trong iPad, thanx!
JOM

3

Swift thực hiện:

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

Bởi vì swift không thực thi phương thức tải lớp khi khởi động, điều quan trọng là phải khởi động dịch vụ này khi khởi chạy ứng dụng:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
  ...    
  KeyboardStateListener.shared.start() 
}

Sử dụng iOS 13, nhanh chóng 5.0 bit cuối cùng này, tải lớp dường như không cần thiết?
user3069232

3

Đây là giải pháp của tôi, nó gói gọn mọi thứ vào một phương thức tĩnh duy nhất và bạn có thể gọi nó ở bất cứ đâu để kiểm tra:

+(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;
}

2

Và đây là cách thực hiện điều đó trong 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");
}

Đừng quên hủy đăng ký:

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

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

Và nếu bạn muốn loại bỏ bàn phím khi nhấn nút "Quay lại":

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

}

1

Hãy thử chức năng này

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;

}

từ: iOS: Làm thế nào để truy cập vào `UIKeyboard`?


1

BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. Nếu nó trả về YES, thì bàn phím đang hoạt động.


1

Để kiểm tra bàn phím thời tiết có xuất hiện hay không, chúng ta có thể sử dụng Bàn phím thông báo xác định trước.

UIKeyboardDidShowNotification, UIKeyboardDidHideNotification

Ví dụ: tôi có thể sử dụng mã sau để nghe thông báo bàn phím

// Nghe bàn phím xuất hiện và biến mất

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

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

trong các phương pháp tôi có thể nhận thông báo

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

- (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{
    // key board is opened
}

1

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

Hoạt động rất tốt đối với tôi (Xcode 10.2, Swift4) chỉ tò mò tại sao không ai ủng hộ cái này?
infinity_coding7

Không, điều đó không hoạt động nếu bàn phím đã được trình bày bởi bộ điều khiển chế độ xem trước đó.
Ricardo

0

Bạn có thể kiểm tra lặp đi lặp lại tất cả các lần xem văn bản, trường văn bản và nhãn trong các lần xem phụ của chế độ xem chính để xem có ai là người phản hồi đầu tiên với một cái gì đó như thế này không:

-(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;
}

Đó là thất bại nếu bạn có bộ điều khiển xem con
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
    }
}

-5

Tôi nghĩ điều này có thể giúp bạn,

+(BOOL)isKeyBoardInDisplay  {

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

    return isExists;
}

cảm ơn,

Naveen Shan


1
Trên iOS 6, Only works vẫn chưa xuất hiện! Khi bàn phím của họ đã được hiển thị một lần, nó sẽ ngừng hoạt động.
James Laurenstin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.