objective-c скрыть - Как я могу программно проверить, присутствует ли клавиатура в приложении iOS?





игре скачать (15)


Я думаю, вам нужно использовать уведомления о клавиатуре:

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

Уведомления о клавиатуре

Когда система показывает или скрывает клавиатуру, она публикует несколько уведомлений о клавиатуре. Эти уведомления содержат информацию о клавиатуре, включая ее размер, которые вы можете использовать для расчетов, которые включают в себя перемещение видов. Регистрация этих уведомлений - единственный способ получить информацию о клавиатуре. Система предоставляет следующие уведомления о событиях, связанных с клавиатурой:

* UIKeyboardWillShowNotification
* UIKeyboardDidShowNotification
* UIKeyboardWillHideNotification
* UIKeyboardDidHideNotification

Для получения дополнительной информации об этих уведомлениях см. Их описания в UIWindow Class Reference. Информацию о том, как показывать и скрывать клавиатуру, см. В разделе «Текст и Интернет».

Мне нужно проверить состояние видимости клавиатуры в приложении iOS.

псевдокод:

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

Как я могу проверить это условие?




Это мое решение, оно инкапсулирует все в один статический метод, и вы можете позвонить ему где угодно, чтобы проверить:

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



Создайте UIKeyboardListener когда вы знаете, что клавиатура не видна, например, вызывая [UIKeyboardListener shared] из 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



Несколько замечаний:

Рекомендуемый шаблон для одноэлементного объекта будет следующим. dispatch_once гарантирует, что класс инициализируется один раз поточно-безопасным способом, а статическая переменная не видна снаружи. И это стандартный GCD, поэтому не нужно знать о деталях низкого уровня Objective-C.

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

    return shared;
}

Обычно вы не хотите знать, является ли клавиатура видимой или нет, но насколько она велика. Клавиатуры не все имеют одинаковый размер. Клавиатуры iPhone меньше клавиатур iPad. Поэтому вам нужно другое свойство @property (readonly, nonatomic) CGRect keyboardRect; который установлен в методе уведомленияShowKeyboard: следующим образом:

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

Важно заметить, что прямоугольник находится в координатах UIWindow и не учитывает поворот экрана. Таким образом, вызывающий может преобразовать этот прямоугольник, вызвав

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

Если пользователь поворачивает экран, пока клавиатура видна, приложению сообщается, что клавиатура скрыта, а затем снова показана. Когда это показано, другие виды, скорее всего, еще не вращаются. Поэтому, если вы сами наблюдаете за событиями, связанными с клавиатурой или шоу, конвертируйте координаты, когда они вам действительно нужны, а не в уведомлении.

Если пользователь разбивает или отстыкует клавиатуру или использует аппаратную клавиатуру, уведомления всегда будут показывать клавиатуру как скрытую. Отмена или слияние клавиатуры отправит уведомление с клавиатуры.

Слушатель должен быть инициализирован, пока клавиатура скрыта, в противном случае первое уведомление будет пропущено, и предполагается, что клавиатура скрыта, когда это не так.

Поэтому очень важно знать, чего вы на самом деле хотите. Этот код полезен для перемещения вещей с клавиатуры (с разделенной или открепленной клавиатурой, это ответственность пользователя). Он не говорит вам, может ли пользователь видеть клавиатуру на экране (в случае разделенной клавиатуры). Он не говорит вам, может ли пользователь печатать (например, когда есть аппаратная клавиатура). Просмотр других окон не работает, если приложение создает другие окна.




Попробуйте эту функцию

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: Как получить доступ к `UIKeyboard`?




Быстрая реализация 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
    } 
}



Использование иерархии подвешенного окна в качестве индикатора для показа клавиатуры - это взломать. Если Apple сменяет свою базовую реализацию, все эти ответы нарушатся.

Правильный способ - следить за отображением клавиатуры и скрывать приложение уведомлений, например, внутри вашего делегата приложения:

В AppDelegate.h:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (assign, nonatomic) BOOL keyboardIsShowing;

@end

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

Затем вы можете проверить, используя:

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

Следует отметить, что уведомления о клавиатуре / скрытии не срабатывают, когда пользователь использует Bluetooth или внешнюю клавиатуру.




Быстрая реализация:

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

Поскольку swift не запускает метод загрузки класса при запуске, важно запустить эту службу при запуске приложения:

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



Вы можете итеративно проверять все текстовые поля, текстовые поля и метки в подзонах родительского представления, чтобы увидеть, являются ли они первыми ответчиками с чем-то вроде этого:

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



... или взять простой способ:

Когда вы вводите textField, он становится первым ответчиком и появляется клавиатура. Вы можете проверить статус клавиатуры с помощью [myTextField isFirstResponder] . Если он вернет YES , клавиатура будет активна.




Я думаю, это может помочь вам,

+(BOOL)isKeyBoardInDisplay  {

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

    return isExists;
}

благодаря,

Навен Шань




BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. Если он вернет YES, клавиатура будет активна.




И вот как это сделать в 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");
}

Не забудьте отменить регистрацию:

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

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

И если вы хотите убрать клавиатуру при нажатии кнопки «Возврат»:

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

}



Это из руководства по программированию текста iOS, опубликованного Apple здесь: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

В основном вызывается «registerForKeyBoardNotifications» в вашем ViewDidLoad. Затем каждый раз, когда клавиатура становится активной, вызывается «keyboardWasShown». И каждый раз, когда клавиатура исчезает, вызывается «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;
}



Ни один из ответов не работал для меня, но это сделало трюк:

android:windowSoftInputMode="adjustNothing"




ios objective-c keyboard