iOS 앱에 키보드가 있는지 프로그래밍 방식으로 어떻게 확인할 수 있습니까?
iOS 앱에서 키보드 가시성 상태를 확인해야합니다.
의사 코드 :
if(keyboardIsPresentOnWindow) {
//Do action 1
}
else if (keyboardIsNotPresentOnWindow) {
//Do action 2
}
이 상태를 어떻게 확인할 수 있습니까?
… 또는 쉬운 방법을 선택하십시오.
textField를 입력하면 첫 번째 응답자가 되고 키보드가 나타납니다. 로 키보드의 상태를 확인할 수 있습니다 [myTextField isFirstResponder]. 를 반환 YES하면 키보드가 활성화 된 것입니다.
drawnonward의 코드는 매우 가깝지만 UIKit의 네임 스페이스와 충돌하여 사용하기 쉽게 만들 수 있습니다.
@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
만들기 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
키보드에 대해 제공되는 알림을 사용해야한다고 생각합니다.
키보드 알림
시스템이 키보드를 표시하거나 숨기면 여러 키보드 알림을 게시합니다. 이러한 알림에는보기 이동과 관련된 계산에 사용할 수있는 키보드 크기 등의 정보가 포함됩니다. 이러한 알림을 등록하는 것은 키보드에 대한 일부 유형의 정보를 얻을 수있는 유일한 방법입니다. 시스템은 키보드 관련 이벤트에 대해 다음 알림을 제공합니다.
* UIKeyboardWillShowNotification * UIKeyboardDidShowNotification * UIKeyboardWillHideNotification * UIKeyboardDidHideNotification이러한 알림에 대한 자세한 내용은 UIWindow Class Reference에서 해당 설명을 참조하십시오. 키보드를 표시하고 숨기는 방법에 대한 자세한 내용은 텍스트 및 웹을 참조하십시오.
키보드 표시에 대한 표시로 창 하위보기 계층 구조를 사용하는 것은 해킹입니다. Apple이 기본 구현을 변경하면 이러한 모든 답변이 깨질 것입니다.
올바른 방법은 키보드 표시를 모니터링하고 App Delegate 내부와 같이 알림 애플리케이션 전체를 숨기는 것입니다.
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;
사용자가 블루투스 또는 외부 키보드를 사용하는 경우 키보드 표시 / 숨기기 알림이 실행되지 않습니다.
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
}
}
이것은 Apple에서 게시 한 iOS 텍스트 프로그래밍 가이드 ( https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html )에서 가져온 것입니다.
기본적으로 ViewDidLoad에서 "registerForKeyBoardNotifications"를 호출합니다. 그런 다음 키보드가 활성화 될 때마다 "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;
}
이제 iOS8에서는이 솔루션이 작동하지 않습니다. 처음에는 IOS4 / 5 용으로 작성되었습니다.
이 솔루션을 시도하십시오.
- (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;
}
몇 가지 관찰 :
싱글 톤 객체에 권장되는 패턴은 다음과 같습니다. 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;과 같이 noticeShowKeyboard : 메소드에 설정된 다른 속성 이 필요합니다.
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];
키보드가 보이는 상태에서 사용자가 화면을 회전하면 앱에 키보드가 숨겨져 있다는 메시지가 표시되고 다시 표시됩니다. 표시 될 때 다른 뷰는 아직 회전되지 않았을 가능성이 높습니다. 따라서 키보드 숨기기 / 표시 이벤트를 직접 관찰하는 경우 알림이 아닌 실제로 필요할 때 좌표를 변환하십시오.
사용자가 키보드를 분리 또는 도킹 해제하거나 하드웨어 키보드를 사용하는 경우 알림은 항상 키보드를 숨김으로 표시합니다. 키보드를 분리하거나 병합하면 "키보드 표시"알림이 전송됩니다.
리스너는 키보드가 숨겨져있는 동안 초기화되어야합니다. 그렇지 않으면 첫 번째 알림이 누락되고 그렇지 않은 경우 키보드가 숨겨져있는 것으로 간주됩니다.
따라서 실제로 원하는 것이 무엇인지 아는 것이 매우 중요합니다. 이 코드는 키보드에서 물건을 이동하는 데 유용합니다 (분할되거나 도킹되지 않은 키보드의 경우 사용자 책임 임). 사용자가 화면에서 키보드를 볼 수 있는지 여부는 알려주지 않습니다 (분할 키보드의 경우). 사용자가 입력 할 수 있는지 여부를 알려주지 않습니다 (예 : 하드웨어 키보드가있는 경우). 앱이 자체적으로 다른 창을 만드는 경우 다른 창을 볼 수 없습니다.
확장 추가
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
}
}
}
그런 다음 키보드가 있는지 확인하십시오.
if UIApplication.shared.isKeyboardPresented {
print("Keyboard presented")
} else {
print("Keyboard is not presented")
}
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)
}
"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;
}
}
이것은 내 솔루션이며 모든 것을 단일 정적 메서드로 캡슐화하며 어디에서나 호출하여 확인할 수 있습니다.
+(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;
}
신속한 구현 :
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()
}
스위프트 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
}
}
}
이 기능을 사용해보십시오
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`에 액세스하는 방법은 무엇입니까?
BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. YES를 반환하면 키보드가 활성화 된 것입니다.
날씨 키보드가 나타나는지 확인하기 위해 키보드 사전 정의 알림을 사용할 수 있습니다.
UIKeyboardDidShowNotification, UIKeyboardDidHideNotification
예를 들어 다음 코드를 사용하여 키보드 알림을 수신 할 수 있습니다.
// 키보드 모양과 사라짐을 듣습니다.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
알림을받을 수있는 방법에서
- (void)keyboardDidShow: (NSNotification *) notifyKeyBoardShow{
// key board is closed
}
- (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{
// key board is opened
}
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
}
}
상위 뷰의 하위 뷰에서 모든 텍스트 뷰, 텍스트 필드 및 레이블을 반복적으로 확인하여 다음과 같은 첫 번째 응답자가 있는지 확인할 수 있습니다.
-(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;
}
이게 도움이 될 것 같아요
+(BOOL)isKeyBoardInDisplay {
BOOL isExists = NO;
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
if ([[keyboardWindow description] hasPrefix:@"<UITextEffectsWindow"] == YES) {
isExists = YES;
}
}
return isExists;
}
감사,
나빈 샨
'IT박스' 카테고리의 다른 글
| PHP에서 int의 최대 값은 얼마입니까? (0) | 2020.08.09 |
|---|---|
| 특정 iPhone / iPod touch 모델 감지 (0) | 2020.08.09 |
| 제목 배경색 설정 (0) | 2020.08.09 |
| 피클 또는 JSON? (0) | 2020.08.09 |
| 언제 규칙 엔진을 사용하지 말아야합니까? (0) | 2020.08.09 |