【问题标题】:Can't hide keyboard in UIViewController stack when UIAlertView is on screen当 UIAlertView 在屏幕上时,无法在 UIViewController 堆栈中隐藏键盘
【发布时间】:2023-03-09 00:30:01
【问题描述】:

我花了一天的大部分时间来追踪一个非常奇怪的情况,即在活动 UITextField 上调用 resignFirstResponder 并没有隐藏键盘,即使文本字段是第一响应者。当我将一个视图控制器推到另一个具有活动文本字段的视图控制器上时,就会发生这种情况。键盘消失(如预期的那样)。但是,如果我通过触摸第二个视图控制器中的文本字段来恢复键盘,则对 resignFirstResponder 的后续调用将无效。

这里是重现问题的简单代码。此代码是一个视图控制器,带有一个用于隐藏键盘的导航栏按钮,另一个用于推送自身的另一个副本(带有确认 UIAlertView)。第一个副本没有问题。但是,如果您按下第二个副本(当第一个副本具有可见键盘时),则无法关闭键盘。仅当推送第二个副本时屏幕上有 UIAlertView(确认)时才会发生这种情况。如果您删除 #define ALERT 行,一切正常。

有人知道这里发生了什么吗?看起来 UIALertView 窗口以某种方式干扰了键盘并使其窗口不消失,从而混淆了下一个视图。除了在 UIALertView 消失后将第二个视图控制器推到计时器上之外,这里还有其他解决方案吗?

抱歉,描述过于复杂。这是可运行的代码。希望代码清晰。

@implementation DemoViewController

- (id) init {
    if (!(self = [super init])) 
        return nil;

    return self; 
}

- (void) dealloc {
    [_inputTextfield release];
    [super dealloc];
}

- (void) loadView {
    UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];

    _inputTextfield = [[UITextField alloc] initWithFrame:CGRectMake(0., 0., 320., 44.)];
    _inputTextfield.borderStyle = UITextBorderStyleRoundedRect;
    _inputTextfield.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    _inputTextfield.keyboardAppearance = UIKeyboardAppearanceAlert;
    _inputTextfield.autocapitalizationType = UITextAutocapitalizationTypeNone;
    _inputTextfield.autocorrectionType = UITextAutocorrectionTypeNo;
    _inputTextfield.keyboardType = UIKeyboardTypeDefault;
    [view addSubview:_inputTextfield];

    self.view = view;
    [view release];
}

- (void) viewWillAppear:(BOOL) animated {
    [super viewWillAppear:animated];

    UIButton *downButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [downButton setTitle: @"keyboard down" forState:UIControlStateNormal];
    [downButton addTarget:self action:@selector(downButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [downButton sizeToFit];    
    self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:downButton] autorelease];

    UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [nextButton setTitle: @"next" forState:UIControlStateNormal];
    [nextButton addTarget:self action:@selector(nextButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [nextButton sizeToFit];
    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:nextButton] autorelease];;

}

- (void) viewWillDisappear:(BOOL) animated {
[super viewWillDisappear:animated];
    [_inputTextfield resignFirstResponder];
}

- (void) downButtonPressed:(id)sender {
    [_inputTextfield resignFirstResponder];
}

#define ALERT

- (void) alertView:(UIAlertView *) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex {
    if (alertView.cancelButtonIndex == buttonIndex) {
        return; 
    }
    [self _nextButtonPressed];
}

- (void) _nextButtonPressed {
    DemoViewController *nextViewController = [[DemoViewController alloc] init];    
    [self.navigationController pushViewController:nextViewController];
    [nextViewController release];
}

- (void) nextButtonPressed:(id)sender {
#ifdef ALERT   
    UIAlertView *alert = [[UIAlertView alloc] init];
    alert.message = @"Next view?";  
    alert.cancelButtonIndex = [alert addButtonWithTitle:@"No"];
    [alert addButtonWithTitle:@"Yes"];
    alert.delegate = self;
    [alert show];
    [alert release];
#else   
    [self _nextButtonPressed];    
#endif
}

【问题讨论】:

  • 在呈现第二个视图控制器之前,您是否尝试过让第一个视图控制器上的第一响应者辞职?
  • 是的,在视图中将消失。抱歉,这并没有进入我的演示代码。但是没有效果。
  • 好的,您是否尝试过使用 [self.view endEditing:YES]?这也应该结束对所有子视图的编辑。
  • 没有。但我相信这只是调用 resignFirstResponder。正在调用 resignFirstResponder。 textField.isFirstResponder == 在调用 resignFirstResponder 之前为 YES,之后为 NO。
  • 我建议你要么尝试:1. 调试它,试着看看你辞职后谁仍然是第一响应者,看看哪个给你带来麻烦 2. 只是截断看看它来自哪里,尝试使用 endEditing。

标签: ios cocoa-touch keyboard uikit uialertview


【解决方案1】:

如果您在辞去第一响应者时运气不好,这里有一些可能会有所帮助的解决方案:

  1. 确定在您最后一次呼吁辞去第一响应者之后谁仍然是第一响应者。

  2. 尝试通过一次调用 self.view(容器视图)让所有第一响应者辞职

    [self.view endEditing:YES];
    
  3. 如果您已尝试上述所有方法但均未奏效,请考虑使用此解决方法。

    -(BOOL)textViewShouldEndEditing:(UITextView *)textView {
      NSArray *wins = [[UIApplication sharedApplication] windows];
      if ([wins count] > 1) {
        UIWindow *keyboardWindow = [wins objectAtIndex:1];
        keyboardWindow.hidden = YES;
      }
      return YES;
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-26
    • 2018-11-19
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多