简体   繁体   English

iOS UITextField在viewWillDisappear上的resignFirstResponder

[英]iOS UITextField resignFirstResponder on viewWillDisappear

I have an application with two simple screen. 我有两个简单屏幕的应用程序。 The first screen always opens same instance of the second screen. 第一个屏幕始终打开第二个屏幕的相同实例。 The second screen has a text field and a button to manually hide keyboard . 第二个屏幕有一个text field和一个手动隐藏keyboardbutton

The resignFirstResponder on viewWillDisappear is not working. viewWillDisappear上的resignFirstResponder无法正常工作。

Case 1: 情况1:

  • Click openSearchButton on the main screen. 单击主屏幕上的openSearchButton。
  • SearchViewController is opened. SearchViewController已打开。
  • Click text field. 单击文本字段。
  • Keyboard becomes visible. 键盘变得可见。
  • Click back button. 单击后退按钮。
  • Application returns to the first screen. 应用程序返回第一个屏幕。
  • Click openSearchButton on the main screen. 单击主屏幕上的openSearchButton。
  • (iOS 10.2) Screen is completely white for a short time. (iOS 10.2)屏幕在短时间内完全变白。
  • SearchViewController is opened. SearchViewController已打开。
  • The text field becomes first responder and keyboard becomes visible. 文本字段成为第一响应者,键盘变为可见。

Case 2: 案例2:

  • Click openSearchButton on the main screen. 单击主屏幕上的openSearchButton。
  • SearchViewController is opened. SearchViewController已打开。
  • Click text field. 单击文本字段。
  • Keyboard becomes visible. 键盘变得可见。
  • Click hideKeyboardButton 单击hideKeyboardButton
  • Keyboard becomes hidden. 键盘变得隐藏。
  • Click back button. 单击后退按钮。
  • Application returns to the first screen. 应用程序返回第一个屏幕。
  • Click openSearchButton on the main screen. 单击主屏幕上的openSearchButton。
  • SearchViewController is opened. SearchViewController已打开。

Code: 码:

         @implementation MainViewController
        -(void) viewDidLoad {
            [super viewDidLoad];
            UIStoryboard *sb = [UIStoryboardWithName:@"Main" bundle:nil];
            self.searchView = (SearchViewController*) [sb instantiateViewControllerWithIdentifier:@"searchView"];
        }

        - (IBAction)openSearchButtonClicked:(id)sender{
            [self.navigationController pushViewController:self.searchView animated:YES];
        }
        @end

        @implementation SearchViewController
        - (void)viewWillDisappear:(BOOL)animated{
            assert(self.searchTextField != nil);    
            [self.searchTextField resignFirstResponder];
            [super viewWillDisappear:animated];
        } 

        - (IBAction)hideKeyboardButtonClicked:(id)sender{
            [self.searchTextField resignFirstResponder];
        }
        @end

I have solved the problem with a workaround. 我通过解决方法解决了这个问题。 I checked stack trace of textFieldDidBeginEditing after re-opening searchView. 重新打开searchView后,我检查了textFieldDidBeginEditing的堆栈跟踪。 Somehow UIKit decides to call becomeFirstResponder on text field. 不知怎的,UIKit决定在文本字段上调用becomeFirstResponder。

My solution is this: not allow text field to be first responder until the view controller appeared. 我的解决方案是:在视图控制器出现之前,不允许文本字段成为第一响应者。 However flashing white screen still occurs on iOS 10.2. 但是,iOS 10.2上仍会出现闪烁的白屏。

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.allowToBecomeFirstResponser = YES;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    return self.allowToBecomeFirstResponser ;
}
- (void)viewWillDisappear:(BOOL)animated{
    self.allowToBecomeFirstResponser = NO;
    [super viewWillDisappear:animated];
}     

0 ??? 0x000000011d54d91c 0x0 + 4787067164, 
1 DEMO 0x000000010c24d880 main + 0, 
2 UIKit 0x000000010d60a227 -[UITextField _becomeFirstResponder] + 481, 
3 UIKit 0x000000010d04d28d -[UIResponder becomeFirstResponder] + 324, 
4 UIKit 0x000000010cf42e03 -[UIView(Hierarchy) becomeFirstResponder] + 99, 
5 UIKit 0x000000010d609ad7 -[UITextField becomeFirstResponder] + 51, 
6 UIKit 0x000000010cf42e3b -[UIView(Hierarchy) deferredBecomeFirstResponder] + 49, 
7 UIKit 0x000000010cf43144 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 175, 
8 UIKit 0x000000010cf43086 -[UIView(Hierarchy) _postMovedFromSuperview:] + 437, 
9 UIKit 0x000000010cf4cf4b -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1604, 
10 UIKit 0x000000010cecf392 -[_UIParallaxDimmingView didMoveToWindow] + 123, 
11 UIKit 0x000000010cf4a9a0 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1482, 
12 UIKit 0x000000010cf4a68e -[UIView(Internal) _didMoveFromWindow:toWindow:] + 696, 
13 UIKit 0x000000010cf43112 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 125, 
14 UIKit 0x000000010cf43086 -[UIView(Hierarchy) _postMovedFromSuperview:] + 437, 
15 UIKit 0x000000010cf4cf4b -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1604, 
16 UIKit 0x000000010cecbc38 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke + 2101, 
17 UIKit 0x000000010cf475ce +[UIView(Animation) performWithoutAnimation:] + 65, 
18 UIKit 0x000000010cecb072 -[_UINavigationParallaxTransition animateTransition:] + 1225, 
19 UIKit 0x000000010d01fe6c -[UINavigationController _startCustomTransition:] + 3038, 
20 UIKit 0x000000010d02b3fe -[UINavigationController _startDeferredTransitionIfNeeded:] + 386, 
21 UIKit 0x000000010d02bf47 -[UINavigationController __viewWillLayoutSubviews] + 43, 
22 UIKit 0x000000010d171509 -[UILayoutContainerView layoutSubviews] + 202,
 -(BOOL) textFieldShouldReturn: (UITextField *) textField
 {
    [textField resignFirstResponder];
    return YES;
 }

But you need to add the UITextFieldDelegate to your SearchViewController to make -(BOOL) textFieldShouldReturn: work in there. 但是你需要将UITextFieldDelegate添加到你的SearchViewController中-(BOOL) textFieldShouldReturn:在那里工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM