在ios 11中,becomeFirstResponder不显示键盘

时间:2017-12-13 16:26:31

标签: ios objective-c keyboard

我试图在加载屏幕后显示键盘,如下所示:

 -(void) viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)];
     tf.borderStyle = UITextBorderStyleRoundedRect;
     tf.text = @"test";

    [self.view addSubview:tf]; 
    if([tf canBecomeFirstResponder]){
        [tf becomeFirstResponder]; // surely this line is called          
     }
 }

此代码适用于ios 8,9,10但不适用于11 。我不确定为什么键盘在ios 11上没有自动显示,而文本字段是聚焦的(有光标)。 在这种情况下,不会调用键盘的通知:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

- (void) keyboardWillShow:(NSNotification *)note {
    NSDictionary *userInfo = [note userInfo];
    CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    DLog(@"Keyboard Height: %f Width: %f", kbSize.height, kbSize.width);
 }

我甚至试过这个:

[tf performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0]; 

但仍无效。

我必须点击文字字段才能调出键盘 Apple有什么更新我不知道吗?

更新:我的项目或所有视图控制器看起来有问题,因为我无法在所有屏幕上显示键盘。但是当我使用上面的代码创建新项目时,它可以很好地工作。 这是问题之一:

enter image description here

正如您所看到的,我必须单击文本字段以显示键盘,而从第二次开始,它可以正常工作。而这个问题只发生在ios 11(模拟器和设备)上 以下是上述搜索字段的代码:

    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 215, 30)];
    textField.backgroundColor = [UIColor clearColor];
    textField.placeholder = @"Enter text to search";
    textField.borderStyle = UITextBorderStyleLine;
    textField.layer.masksToBounds=YES;
    textField.layer.borderColor=[[UIColor lightGrayColor]CGColor];
    textField.layer.borderWidth= 1.0f;
    textField.returnKeyType = UIReturnKeySearch;
    textField.delegate = self;
    textField.clearButtonMode = UITextFieldViewModeAlways;
    [UIView transitionWithView:self.navigationController.navigationBar
                  duration:0.55f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    self.navigationItem.titleView = textField;
                } completion:^(BOOL finished) {
                    [textField becomeFirstResponder];
                }];

我想知道是否有任何导致冲突的键盘?

6 个答案:

答案 0 :(得分:3)

我创建了一个新项目并尝试了您的代码。它在模拟器和设备iOS11上都能正常工作。显示键盘并调用通知。这是我试过的代码。

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(keyboardWillShow:)
                                               name:UIKeyboardWillShowNotification
                                             object:nil];
}

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  UITextField* tf = [[UITextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)];
  tf.borderStyle = UITextBorderStyleRoundedRect;
  tf.text = @"test";

  [self.view addSubview:tf];
  if ([tf canBecomeFirstResponder]) {
    [tf becomeFirstResponder];  // surely this line is called
  }
}

- (void)keyboardWillShow:(NSNotification*)note {
  NSDictionary* userInfo = [note userInfo];
  CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

  NSLog(@"Keyboard Height: %f Width: %f", kbSize.height, kbSize.width);
}

@end

您应该检查DLog方法。我认为键盘的通知已被调用,但由于DLog方法没有记录任何内容。

enter link description here

答案 1 :(得分:1)

试试这个。我觉得textField对象在完成块中变为null,并且你在那里调用becomeFirstResponder

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 215, 30)];
textField.backgroundColor = [UIColor clearColor];
textField.placeholder = @"Enter text to search";
textField.borderStyle = UITextBorderStyleLine;
textField.layer.masksToBounds=YES;
textField.layer.borderColor=[[UIColor lightGrayColor]CGColor];
textField.layer.borderWidth= 1.0f;
textField.returnKeyType = UIReturnKeySearch;
textField.delegate = self;
textField.clearButtonMode = UITextFieldViewModeAlways;
[UIView transitionWithView:self.navigationController.navigationBar
              duration:0.55f
               options:UIViewAnimationOptionTransitionCrossDissolve
            animations:^{
                self.navigationItem.titleView = textField;
            } completion:^(BOOL finished) {
                [((UITextField *)self.navigationItem.titleView) becomeFirstResponder];
            }];

答案 2 :(得分:1)

试试这个;

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    [theTextField resignFirstResponder];
    return NO;
}

- (void)viewWillAppear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}


- (void)keyboardWillShow:(NSNotification *)notification {
        CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
}

- (void)keyboardWillHide:(NSNotification *)notification {

}

答案 3 :(得分:0)

这真的很奇怪,因为这个问题可以在显示UIAlertView后显示 所以当我尝试在显示带有上述代码的键盘之前添加UIAlertView加载指示符(以及几秒钟后自动dimiss),如this之前,它可以正常工作。
不知道我的项目的根本原因,但它的工作原理 它只发生在ios 11上。

答案 4 :(得分:0)

在我的情况下,问题是我有2个UIWindow对象,而我用来添加UI元素的那个对象未设置为键窗口,而键盘窗口的级别较低,所以键盘被另一个覆盖了。窗口。我只需要在第二个窗口中调用makeKeyAndVisible()john07的评论帮助我弄清楚了这一点。有关更多参考,请检查:https://developer.apple.com/library/archive/qa/qa1813/_index.html

答案 5 :(得分:0)

当尚未在屏幕上绘制TextField时,beginFirstResponder()将不起作用。例如,当它被隐藏而不被绘制时。然后,在绘制完之后,需要调用beginFirstResponder()。也许这会有所帮助:

DispatchQueue.main.async {
    tf.becomeFirstResponder()
}