【问题标题】:becomeFirstResponder not show keyboard in ios 11becomeFirstResponder 在 ios 11 中不显示键盘
【发布时间】:2018-05-27 15:08:08
【问题描述】:

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

 -(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 有什么我不知道的更新吗?

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

如您所见,我必须单击文本字段才能显示键盘,并且从第二次开始,它可以正常工作。而且这个问题只发生在 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];
                }];

不知道有没有什么东西会导致键盘冲突?

【问题讨论】:

  • 你在模拟器上运行你的代码??如果是,通过选择模拟器切换硬件键盘,然后点击 command+shift+k
  • 为什么要在viewDidAppear 方法中添加文本字段?可以多次调用。您应该在viewDidLoad 中添加文本字段。您仍然可以使其成为viewDidAppear 中的第一响应者。
  • @SandeepBhandari 我在设备和模拟器上都进行了测试。我已经使用切换键盘。如果我手动单击文本字段,键盘可以正确显示,但我想在屏幕加载后自动显示
  • @rmaddy 我知道,这是我尝试测试的唯一方法,以确保屏幕已加载。正如你所说,我只是在 viewdidload 中添加视图并在 viewDidAppear 中设置第一响应者,但仍然无法正常工作,键盘没有显示
  • @R4 thanx 但我解决了问题。我的应用程序中有 2 个窗口,并将 makeKeyAndVisible 设置为另一个窗口。那位裁判帮助了我developer.apple.com/library/content/qa/qa1813/_index.html

标签: ios objective-c keyboard


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我创建了一个新项目并尝试了您的代码。它在模拟器和设备 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 方法没有记录任何内容。

    【讨论】:

    • 我已经运行调试,而不仅仅是日志。而keyboardWillShow 仅在我单击 UITextField 以强制显示键盘时被调用。键盘是否总是显示在您身边而不触摸文本字段?
    • 当我检查时,键盘总是显示在模拟器和设备上。你可以在这里看到它media.giphy.com/media/3ohjUUSFCXvimPR7l6/giphy.gif
    • 谢谢。当我使用上述代码创建新项目时,它可以工作。我在视图控制器中的其他代码有问题
    • 很好的答案!我想为其他人补充说,用户在 viewDidAppear 中正确使用了“becomeFirstResponder”。例如,如果您在 viewWillAppear 中使用“becomeFirstResponder”,那么如果该视图尚未添加到视图层次结构中,则 canBecomeFirstResponder 可能会返回 false。您可以保证它已添加到 viewDidLoad 中的视图层次结构中,但我认为(可能是错误的)将“canBecomeFirstResponder”放入 viewDidAppear 可确保也添加了观察者(我在 viewDidLoad 中遇到了观察者问题)。跨度>
    【解决方案3】:

    试试这个。我觉得 textField 对象在完成块中为空,而您在此调用 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];
                }];
    

    【讨论】:

      【解决方案4】:

      试试这个;

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

      【讨论】:

      • 我试过这个。问题是键盘不显示,所以通知不起作用。只有当我点击文本字段时它才能工作
      【解决方案5】:

      在我的情况下,问题是,我有 2 个UIWindow 对象,而我用来添加 UI 元素的对象没有设置为键窗口,并且键盘窗口的级别较低,因此键盘被我的另一个窗口覆盖。我只需要在第二个窗口上拨打makeKeyAndVisible()john07 的评论帮助我解决了这个问题。如需进一步参考检查:https://developer.apple.com/library/archive/qa/qa1813/_index.html

      【讨论】:

        【解决方案6】:

        真的很奇怪,因为这个问题可以在显示UIAlertView后修复
        因此,当我尝试在显示带有上述代码的键盘之前添加带有加载指示器的UIAlertView(并在几秒钟后自动关闭),如this,它可以正常工作。
        不知道我的项目的根本原因,但它确实有效。
        而且它只发生在 ios 11 上。

        【讨论】:

          猜你喜欢
          • 2017-12-19
          • 1970-01-01
          • 2019-03-08
          • 1970-01-01
          • 1970-01-01
          • 2020-03-17
          • 1970-01-01
          • 1970-01-01
          • 2021-06-27
          相关资源
          最近更新 更多