在 iOS 6 中,-[UITextField becomeFirstResponder] 在 -viewWillAppear 中不起作用:

Posted

技术标签:

【中文标题】在 iOS 6 中,-[UITextField becomeFirstResponder] 在 -viewWillAppear 中不起作用:【英文标题】:In iOS 6, -[UITextField becomeFirstResponder] doesn't work in -viewWillAppear: 【发布时间】:2012-11-20 18:46:18 【问题描述】:

ios 5.1 和 iOS 5.0 中它可以工作,但在 iOS 6.0 中键盘不显示。

- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];
    UITextField *textField = self.emailAddressTextField;
    [textField becomeFirstResponder];

现在我将逻辑移至-viewDidAppear:

// This works but is not desirable.
- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    UITextField *textField = self.emailAddressTextField;
    [textField becomeFirstResponder];

这可行,但不可取。视图加载后显示键盘上滑动画。

我希望键盘显示为向左滑动动画显示正在加载到导航控制器中的视图。

有人知道如何在 iOS 6 中显示视图时加载键盘吗?

更新

根据@Duck 的反馈,我进行了更多测试。这似乎特定于 UITableViewCells 中包含的 UITextFields。

有人有什么建议吗?

第一个解决方案

所以一个完整的描述。这是一个带有两个静态单元格(电子邮件和密码)的表格视图。在分配了表格页脚视图的视图中有一个登录按钮。这两个单元格中有一个文本字段,属于自定义类型 SICOTextFieldCell。

我的解决方案是在登录按钮后面(在表格页脚视图中)放置一个假文本字段。

- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];
    UITextField *textField = self.SICO_fakeTextField;
    [textField becomeFirstResponder];


- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    UITextField *textField = self.SICO_emailAddressTextField;
    [textField becomeFirstResponder];

新解决方案

根据@stm 的回答,我想出了一个新的(更好的?)解决方案。

我的解决方案是致电-selectRowAtIndexPath:animated:scrollPosition:-[SICOTextFieldCell setSelected:animated:],这是一个自定义表格视图单元格,调用 [self.textField becomeFirstResponder],它神奇地正确绘制了键盘。它仍然是一个 hack,但它是一个更干净的 hack。

@interface SICOLogInViewController ()
@property (readonly, nonatomic) UITextField *SICO_emailAddressTextField;
@property (readonly, nonatomic) UITextField *SICO_passwordTextField;
@end

@implementation SICOLogInViewController

- (IBAction)logIn

    // Controller Details


#pragma mark Private

- (UITextField *)SICO_textFieldForRowAtIndexPath:(NSIndexPath *)indexPath

    SICOTextFieldCell *cell = (SICOTextFieldCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    return cell.textField;


#pragma mark View lifecycle

- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];
    [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
                                animated:NO scrollPosition:UITableViewScrollPositionTop];


#pragma mark UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField

    switch (textField.returnKeyType) 
        case UIReturnKeyGo:   [self logIn];                                       break;
        case UIReturnKeyNext: [self.SICO_passwordTextField becomeFirstResponder]; break;
        default: break;
    
    return YES;


#pragma mark Properties

- (UITextField *)SICO_emailAddressTextField

    return [self SICO_textFieldForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];


- (UITextField *)SICO_passwordTextField

    return [self SICO_textFieldForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];


@end

【问题讨论】:

您是否尝试过将该代码放入viewWillAppear @yulz 是的,我的原始代码在-viewWillAppear: 您的代码中还有其他问题,这应该可以正常运行。如果您想快速修复,请调用 [textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1f];而不是 [textField becomeFirstResponder];。这会将第一响应者设置为 1/10 秒后,大概会给出您可能有时间完成运行的任何有问题的代码,并且不会在 1/10 秒后停止它。不过,这是一个草率的解决方法,并不是理想的解决方案。 @Anton 首先,我想说这行得通。问题是效果很奇怪。视图从右侧滑入,然后键盘在 1/2 秒后从右侧滑入。这比从右侧滑入然后键盘从底部向上滑动 1/2 秒后的视图要好。我使用了 0 的延迟。[textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0f] 很高兴听到至少解决方法有效。顺便说一句,如果你要延迟为0,你可以打电话给[textField performSelector:@selector(becomeFirstResponder)] 【参考方案1】:

尝试在创建单元格后在 cellForRowAtIndexPath 方法中调用它,或者在包含该文本字段的 tableViewCell 的 viewWillAppear 中调用它。

如果这给您相同的结果并且您仍然希望键盘出现在之前,我会使用“假”文本字段在开头显示键盘。我的猜测是在 viewWillAppear 之前没有添加您的 textField。

【讨论】:

我支持“假”文本字段解决方案。 我认为“假”文本字段是赢家!谢谢k20。我会在一分钟内发布我的解决方案。【参考方案2】:

我在 viewWillAppear 中完全尝试了您的代码,iOS6 和它似乎工作正常。 当您推到不同的视图时,您试图让键盘已经显示,对吗?

【讨论】:

我很抱歉,但这并没有真正的帮助。它指出这个问题并不普遍,所以我会更新我的问题。【参考方案3】:

我目前正在编写自己的输入表单工具包,并在这个问题上苦苦挣扎了几个小时。 在发现我的编码没问题后,我发现这个问题指出了 iOS 6 中可能存在的故障,并为此制定了解决方案。

如果您有(或创建)一个自定义 UITableViewCell,一个简单的解决方案就是子类化 - (void) layoutSubviews;并检查单元格的 UITextField 是否应该是第一响应者(即通过检查文本字段是否与委托中设置的焦点字段相同)。 如果是这样,只需调用 - (BOOL) becomeFirstResponder;在你的 UITextField 上(再次)。

这绝对是比创建“假” UITextField 更好的解决方案;)

【讨论】:

【参考方案4】:

-viewWillAppear 可能不会在 iOS6 中调用?你试过把你的代码放在- (void)viewWillLayoutSubviews吗?

【讨论】:

我可以验证-viewWillAppear: 正在被调用。

以上是关于在 iOS 6 中,-[UITextField becomeFirstResponder] 在 -viewWillAppear 中不起作用:的主要内容,如果未能解决你的问题,请参考以下文章

iOS 6 UITextField Secure - 如何检测退格清除所有字符?

添加 UITextField 作为 UITableViewCell 的子视图在 IOS 6 中工作正常,但在 IOS 7 中它不起作用?

如何使用UItextfield在xamarin IOS中只进行前进和后退文本框?

在 iOS 中使用 UITextField 条目作为数组

iOS 6.1 中的 *** 从 TextFieldOnEditingDidEnd 内部调用成为第一响应者时

IOS 13:UITextField rightView的间距问题