Не удается скрыть клавиатуру в стеке UIViewController, когда UIAlertView находится на экране - PullRequest
5 голосов
/ 29 октября 2011

Я провел большую часть дня, выслеживая очень странный случай, когда вызов resignFirstResponder на активном UITextField не скрывал клавиатуру, хотя текстовое поле было первым респондентом. Это происходит, когда я помещаю контроллер представления поверх другого контроллера представления с активным текстовым полем. Клавиатура уходит (как и ожидалось). Но если я верну клавиатуру обратно, коснувшись текстового поля в контроллере второго представления, последующие вызовы resignFirstResponder не будут иметь никакого эффекта.

Вот простой код для воспроизведения проблемы. Этот код является контроллером представления с кнопкой навигационной панели, чтобы скрыть клавиатуру, и другой, чтобы нажать другую копию самого себя (с подтверждением UIAlertView). Первый экземпляр работает без проблем. Тем не менее, если вы нажмете 2-ую копию (когда первая копия имеет видимую клавиатуру), невозможно от нее отказаться Это происходит только в том случае, если на экране отображается 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 Ответ

4 голосов
/ 29 октября 2011

Если вам не повезло в отставке ваших первых респондентов, вот несколько решений, которые могут помочь:

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