2011-10-29 29 views
5

Tôi đã dành hầu hết một ngày theo dõi xuống một trường hợp rất lạ khi gọi resignFirstResponder trên UITextField đang hoạt động không ẩn bàn phím, mặc dù trường văn bản là người trả lời đầu tiên . Điều này xảy ra khi tôi đẩy một bộ điều khiển xem trên đầu trang của một bộ điều khiển xem khác với một trường văn bản đang hoạt động. Bàn phím biến mất (như mong đợi). Nhưng nếu tôi mang bàn phím trở lại bằng cách chạm vào một trường văn bản trong bộ điều khiển chế độ xem thứ 2, các cuộc gọi tiếp theo để từ chốiFirstResponder sẽ không có hiệu lực.Không thể ẩn bàn phím trong ngăn xếp UIViewController khi UIAlertView đang ở trên màn hình

Đây là mã đơn giản để tái tạo sự cố. Mã này là một bộ điều khiển xem với một nút thanh nav để ẩn bàn phím, và một cái khác để đẩy một bản sao của chính nó (với một UIAlertView xác nhận). Bản sao đầu tiên hoạt động mà không có vấn đề gì. Tuy nhiên, nếu bạn đẩy bản sao thứ 2 (khi bản sao đầu tiên có bàn phím hiển thị), bạn không thể loại bỏ bàn phím. Điều này chỉ xảy ra nếu có một UIAlertView (xác nhận) trên màn hình khi bản sao thứ hai được đẩy. Nếu bạn xóa đường dây #define ALERT, mọi thứ sẽ hoạt động.

Có ai biết điều gì đang xảy ra ở đây không? Dường như cửa sổ UIALertView bằng cách nào đó đang can thiệp vào bàn phím và giữ cho cửa sổ của nó không bị biến mất, điều này sẽ gây nhầm lẫn cho khung nhìn tiếp theo. Có bất kỳ giải pháp ở đây khác hơn là đẩy bộ điều khiển xem 2 trên một bộ đếm thời gian sau khi UIALertView đã biến mất?

Xin lỗi vì mô tả phức tạp. Đây là mã runnable. Tôi hy vọng rằng mã này rõ ràng.

@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 
} 
+0

Các bạn đã cố gắng từ chức responder đầu tiên trên bộ điều khiển xem đầu tiên trước khi trình bày bộ điều khiển xem thứ hai? –

+0

Có, trong chế độ xemLàm mờ. Xin lỗi, điều đó đã không biến nó thành mã demo của tôi. Nhưng nó không có tác dụng. – wombat57

+0

Ok, Bạn đã thử sử dụng [self.view endEditing: YES] chưa? điều này cũng sẽ kết thúc chỉnh sửa trên tất cả các bản xem phụ. –

Trả lời

4

Nếu bạn đã xui xẻo từ chức phản ứng đầu tiên của bạn, sau đây là một số giải pháp có thể giúp:

  1. Xác định người vẫn responder đầu tiên sau khi cuộc gọi cuối cùng của bạn phải từ chức responder đầu tiên.

  2. Cố gắng từ chức tất cả các phản ứng đầu tiên bởi một cuộc gọi duy nhất để self.view (xem thùng chứa)

    [self.view endEditing:YES]; 
    
  3. CHỈ nếu bạn đã thử tất cả các phương pháp trên và không làm việc, xem xét sử dụng workaround này .

    -(BOOL)textViewShouldEndEditing:(UITextView *)textView { 
        NSArray *wins = [[UIApplication sharedApplication] windows]; 
        if ([wins count] > 1) { 
        UIWindow *keyboardWindow = [wins objectAtIndex:1]; 
        keyboardWindow.hidden = YES; 
        } 
        return YES; 
    } 
    
Các vấn đề liên quan