Ich muss den Zustand der Tastatursichtbarkeit in meiner iOS-App überprüfen.
Pseudocode:
if(keyboardIsPresentOnWindow) {
//Do action 1
}
else if (keyboardIsNotPresentOnWindow) {
//Do action 2
}
Wie kann ich diesen Zustand überprüfen?
Ich muss den Zustand der Tastatursichtbarkeit in meiner iOS-App überprüfen.
Pseudocode:
if(keyboardIsPresentOnWindow) {
//Do action 1
}
else if (keyboardIsNotPresentOnWindow) {
//Do action 2
}
Wie kann ich diesen Zustand überprüfen?
Antworten:
… Oder nehmen Sie den einfachen Weg:
Wenn Sie ein Textfeld eingeben, wird es zum Ersthelfer und die Tastatur wird angezeigt. Sie können den Status der Tastatur mit überprüfen [myTextField isFirstResponder]
. Wenn es zurückkehrt YES
, ist die Tastatur aktiv.
Der Code von drawonward ist sehr eng, kollidiert jedoch mit dem UIKit-Namespace und könnte einfacher zu verwenden sein.
@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
+load
ist eine spezielle Methode, die von der Objective-C-Laufzeit aufgerufen wird. Es wird für jede Klasse aufgerufen, nachdem die App-Binärdatei geladen wurde, aber bevor die main()
Funktion eingegeben wird. Es gibt keine Garantie dafür, dass ein Autorelease-Pool aktiv ist.
NSAutoreleasePool
alloc
/ release
kann nun durch rund um den Code in ersetzt werden@autoreleasepool { }
Erstellen Sie eine, UIKeyboardListener
wenn Sie wissen, dass die Tastatur nicht sichtbar ist, z. B. durch Aufrufen [UIKeyboardListener shared]
von 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
+(void)load
init für diese Listener-Klasse aufrufen, damit sie generisch als Drag-and-Drop in jedes Projekt funktioniert und vom zweiten App-Start an initialisiert wird, anstatt dass Sie daran denken müssen, sie irgendwo zu initiieren.
Ich denke, Sie müssen die Benachrichtigungen verwenden, die über die Tastatur bereitgestellt werden:
Tastaturbenachrichtigungen
Wenn das System die Tastatur ein- oder ausblendet, werden mehrere Tastaturbenachrichtigungen gesendet. Diese Benachrichtigungen enthalten Informationen zur Tastatur, einschließlich ihrer Größe, die Sie für Berechnungen verwenden können, bei denen Ansichten verschoben werden. Die Registrierung für diese Benachrichtigungen ist die einzige Möglichkeit, Informationen über die Tastatur abzurufen. Das System liefert die folgenden Benachrichtigungen für Ereignisse im Zusammenhang mit der Tastatur:
* UIKeyboardWillShowNotification * UIKeyboardDidShowNotification * UIKeyboardWillHideNotification * UIKeyboardDidHideNotification
Weitere Informationen zu diesen Benachrichtigungen finden Sie in den Beschreibungen in der UIWindow-Klassenreferenz. Informationen zum Ein- und Ausblenden der Tastatur finden Sie unter Text und Web.
Swift 3-Implementierung
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
}
}
Die Verwendung der Fenster-Unteransichtshierarchie als Anzeige für die Tastaturanzeige ist ein Hack. Wenn Apple die zugrunde liegende Implementierung ändert, werden alle diese Antworten unterbrochen.
Der richtige Weg wäre, das Ein- und Ausblenden von Benachrichtigungen auf der Tastatur zu überwachen, z. B. in Ihrem App-Delegaten:
In AppDelegate.h:
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (assign, nonatomic) BOOL keyboardIsShowing;
@end
In 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;
}
Dann können Sie überprüfen mit:
BOOL keyboardIsShowing = ((AppDelegate*)[UIApplication sharedApplication].delegate).keyboardIsShowing;
Es ist zu beachten, dass die Benachrichtigungen zum Ein- und Ausblenden der Tastatur nicht ausgelöst werden, wenn der Benutzer eine Bluetooth- oder externe Tastatur verwendet.
Fügen Sie eine Erweiterung hinzu
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
}
}
}
Überprüfen Sie dann, ob die Tastatur vorhanden ist.
if UIApplication.shared.isKeyboardPresented {
print("Keyboard presented")
} else {
print("Keyboard is not presented")
}
guard let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow") else { return false }; return UIApplication.shared.windows.contains(where: { $0.isKind(of: keyboardWindowClass) })
Dies stammt aus dem von Apple hier veröffentlichten iOS-Textprogrammierungshandbuch: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
Rufen Sie grundsätzlich "registerForKeyBoardNotifications" in Ihrem ViewDidLoad auf. Jedes Mal, wenn die Tastatur aktiv wird, wird "keyboardWasShown" aufgerufen. Und jedes Mal, wenn die Tastatur verschwindet, wird "keyboardWillBeHidden" aufgerufen.
// 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;
}
In iOS8 funktioniert diese Lösung natürlich nicht. Es wurde ursprünglich für IOS4 / 5 geschrieben.
Versuchen Sie diese Lösung:
- (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;
}
Einige Beobachtungen:
Das empfohlene Muster für ein Singleton-Objekt lautet wie folgt. dispatch_once stellt sicher, dass die Klasse einmal threadsicher initialisiert wird und die statische Variable außerhalb nicht sichtbar ist. Da es sich um eine Standard-GCD handelt, müssen Sie keine Details zu Objective-C auf niedriger Ebene kennen.
+ (KeyboardStateListener *)sharedInstance
{
static KeyboardStateListener* shared;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[KeyboardStateListener alloc] init];
// Other initialisations
});
return shared;
}
Normalerweise möchten Sie nicht wissen, ob die Tastatur sichtbar ist oder nicht, sondern wie groß sie ist. Tastaturen haben nicht alle die gleiche Größe. iPhone-Tastaturen sind kleiner als iPad-Tastaturen. Sie möchten also eine andere Eigenschaft, @property (readonly, nonatomic) CGRect keyboardRect;
die in der noteShowKeyboard: -Methode wie folgt festgelegt ist:
NSValue* value = notification.userInfo [UIKeyboardFrameEndUserInfoKey];
_keyboardRect = value.CGRectValue;
Es ist wichtig zu beachten, dass sich das Rechteck in UIWindow-Koordinaten befindet und die Bildschirmdrehung nicht berücksichtigt. Der Anrufer würde dieses Rechteck also durch Aufrufen konvertieren
KeyboardStateListener* listener = [KeyboardStateListener sharedInstance];
CGRect windowRect = listener.keyboardRect;
CGRect viewRect = [myView convertRect:windowRect fromView:self.window];
Wenn der Benutzer den Bildschirm dreht, während die Tastatur sichtbar ist, wird der App mitgeteilt, dass die Tastatur ausgeblendet und dann erneut angezeigt wird. Wenn es angezeigt wird, werden andere Ansichten höchstwahrscheinlich noch nicht gedreht. Wenn Sie also selbst Ereignisse zum Ausblenden / Anzeigen der Tastatur beobachten, konvertieren Sie die Koordinaten, wenn Sie sie tatsächlich benötigen, nicht in der Benachrichtigung.
Wenn der Benutzer die Tastatur teilt oder abdockt oder eine Hardwaretastatur verwendet, wird die Tastatur in den Benachrichtigungen immer als ausgeblendet angezeigt. Wenn Sie die Tastatur abdocken oder zusammenführen, wird eine Benachrichtigung "Tastatur angezeigt" gesendet.
Der Listener muss initialisiert werden, während die Tastatur ausgeblendet ist. Andernfalls wird die erste Benachrichtigung übersehen und es wird davon ausgegangen, dass die Tastatur ausgeblendet ist, wenn dies nicht der Fall ist.
Es ist also sehr wichtig zu wissen, was Sie tatsächlich wollen. Dieser Code ist nützlich, um Dinge aus dem Weg zu räumen (bei einer geteilten oder nicht angedockten Tastatur liegt dies in der Verantwortung des Benutzers). Es sagt Ihnen nicht, ob der Benutzer eine Tastatur auf dem Bildschirm sehen kann (im Fall einer geteilten Tastatur). Es sagt Ihnen nicht, ob der Benutzer tippen kann (zum Beispiel, wenn eine Hardwaretastatur vorhanden ist). Das Betrachten anderer Fenster funktioniert nicht, wenn die App andere Fenster selbst erstellt.
Schnelle Implementierung:
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
}
}
Da swift nicht Klasse ausführen Last Methode beim Start ist es wichtig , diesen Dienst auf App - Start zu starten:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
...
KeyboardStateListener.shared.start()
}
Dies ist meine Lösung, sie kapselt alles in einer einzigen statischen Methode, und Sie können sie überall aufrufen, um Folgendes zu überprüfen:
+(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;
}
Und so geht's in 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");
}
Vergessen Sie nicht, die Registrierung aufzuheben:
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIKeyboardDidShowNotification,
object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self,
name: UIKeyboardWillHideNotification,
object: nil)
}
Und wenn Sie die Tastatur beim Drücken der "Return" -Taste schließen möchten:
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;
}
}
Probieren Sie diese Funktion aus
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;
}}
BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. Wenn JA zurückgegeben wird, ist die Tastatur aktiv.
Um zu überprüfen, ob die Wettertastatur angezeigt wird, können Sie die vordefinierten Tastaturbenachrichtigungen verwenden.
UIKeyboardDidShowNotification, UIKeyboardDidHideNotification
Zum Beispiel kann ich den folgenden Code verwenden, um die Tastaturbenachrichtigung abzuhören
// Achten Sie auf das Erscheinen und Verschwinden der Tastatur
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
In den Methoden kann ich Benachrichtigungen erhalten
- (void)keyboardDidShow: (NSNotification *) notifyKeyBoardShow{
// key board is closed
}
- (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{
// key board is opened
}
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
}
}
}
Sie können alle Textansichten, Textfelder und Beschriftungen in den Unteransichten einer übergeordneten Ansicht iterativ überprüfen, um festzustellen, ob es sich bei den ersten um Antworten handelt.
-(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;
}
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
}
}
Ich denke, das kann dir helfen,
+(BOOL)isKeyBoardInDisplay {
BOOL isExists = NO;
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
if ([[keyboardWindow description] hasPrefix:@"<UITextEffectsWindow"] == YES) {
isExists = YES;
}
}
return isExists;
}
Vielen Dank,
Naveen Shan