当UIAlertView在屏幕上时,无法在UIViewController堆栈中隐藏键盘

时间:2011-10-29 00:33:08

标签: ios cocoa-touch keyboard uikit uialertview

我花了大约一天的时间来追踪一个非常奇怪的情况,即在活动的UITextField上调用resignFirstResponder并没有隐藏键盘,即使textfield是第一个响应者。当我将视图控制器推送到具有活动文本字段的另一个视图控制器之上时,会发生这种情况。键盘消失(正如预期的那样)。但是,如果我通过触摸第二个视图控制器中的文本字段将键盘带回,则后续调用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
}

1 个答案:

答案 0 :(得分:4)

如果你运气不好辞职的第一响应者,这里有一些可能有帮助的解决方案:

  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;
    }