静态表视图 - 键盘隐藏的 UITextField

Posted

技术标签:

【中文标题】静态表视图 - 键盘隐藏的 UITextField【英文标题】:Static Table View - UITextField hidden by Keyboard 【发布时间】:2012-12-12 16:48:49 【问题描述】:

也许这是一个反复出现的问题,但我被这个问题和一些 ios 概念所困扰。我有一个 ViewController,其中有一个 静态表视图三个部分,每个部分都有一些 。在行内我有 UITextFields。我想要做的是阻止键盘隐藏我的底部屏幕 UI 文本字段。我刚刚尝试了来自Managing the Keyboard 的苹果解决方案,但是由于我没有将滚动视图背后的概念附加到静态表格视图中,因此我无法将这个想法实施到我的项目中。大家有没有推荐的地方学习呢?抱歉,如果无法解释我要做什么。我有点迷茫。

任何帮助将不胜感激。

非常感谢, 马科斯。

【问题讨论】:

【参考方案1】:

我不得不做类似的事情,这是我的代码,希望它可以帮助你。

- (void)keyboardWasShown:(NSNotification*)aNotification

    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    CGRect aRect = self.bounds;
    aRect.size.height -= kbSize.height;
    CGRect activeRect = [activeTextField convertRect:activeTextField.frame toView:self];

    if (!CGRectContainsPoint(aRect, activeRect.origin) ) 
        CGPoint scrollPoint = CGPointMake(0.0, activeRect.origin.y-kbSize.height+10);
        [scrollView setContentOffset:scrollPoint animated:YES];
    


// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification

    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;


- (void)textFieldDidBeginEditing:(UITextField *)textField

    self.activeTextField = textField;


- (void)textFieldDidEndEditing:(UITextField *)textField

    self.activeTextField = nil;


- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    [textField resignFirstResponder];
    return NO;

另外,请确保在加载视图时设置通知观察者,如下所示:

[[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWasShown:)
                                                     name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillBeHidden:)
                                                     name:UIKeyboardWillHideNotification object:nil];

只需将 activeTextField 定义为 UITextField 并确保您想要移动的所有内容都包含在您的 scrollView 中(在您的情况下,您可以将 viewController 更改为 scrollView)。另外,请确保您的 scrollView 的 contentSize 至少为 self.bounds.size。

希望这会有所帮助。

【讨论】:

感谢您的快速回复。你的scrollView是tableView吗?那么 self.bounds 呢?什么是自我?我的班级自己是一个 UITableViewController。 我的scrollView是一个UIScrollView。这个 scrollView 实际上应该在您的 UITableView 之上,但可能会包含在 UIViewController 本身中,使您的 self 成为 UIViewController 和 self.view.bounds 将是您应该将 scrollView 的 contentSize 设置为的值。 是的,我知道了,它在纵向模式下工作。因为我旋转到横向它不再起作用了。 您可能需要在旋转时重置滚动视图的内容大小。【参考方案2】:

我只需要在我的应用程序中执行此操作 - Stakenborg 的回答让我达到了 80%,但我添加了一些额外的改进来专门用于 TableViews。

主要内容是:

TableViews 已经有 insets,所以我们需要对它们进行添加或减去。 我还想滚动,以便我正在编辑的单元格位于一个可以看到的好位置。

第二部分需要一点间接性——文本字段属于我的自定义单元格,所以我需要通过向 UITableViewController 发送消息来响应那里的 BeginEditing 消息。

这就是所有内容的结合方式。在 UITableViewController 中:

@property (nonatomic, strong) NSIndexPath *editCellIndexPath;
@property (nonatomic) bool keyboardShowing;

//....

- (void)setEditRow:(UITableViewCell *)cell

    self.editCellIndexPath = [self.tableView indexPathForCell:cell];
    if (self.keyboardShowing)
    
        [self.tableView scrollToRowAtIndexPath:self.editCellIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:true];
    


- (void)keyboardWillShow:(NSNotification *)sender

    CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    UIEdgeInsets edgeInsets = [self.tableView contentInset];
    edgeInsets.bottom += kbSize.height;
    UIEdgeInsets scrollInsets = [self.tableView scrollIndicatorInsets];
    scrollInsets.bottom += kbSize.height;

    self.keyboardShowing = true;

    [UIView animateWithDuration:duration animations:^
        [self.tableView setContentInset:edgeInsets];
        [self.tableView setScrollIndicatorInsets:scrollInsets];
    ];


- (void)keyboardWillHide:(NSNotification *)sender

    CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    UIEdgeInsets edgeInsets = [self.tableView contentInset];
    edgeInsets.bottom -= kbSize.height;
    UIEdgeInsets scrollInsets = [self.tableView scrollIndicatorInsets];
    scrollInsets.bottom -= kbSize.height;

    self.keyboardShowing = false;

    [UIView animateWithDuration:duration animations:^
        [self.tableView setContentInset:edgeInsets];
        [self.tableView setScrollIndicatorInsets:scrollInsets];
    ];

然后我的每个自定义 UITableViewCells 中的 owningController 都有一个弱属性,并让控制器知道我的单元格何时被文本编辑。我在一个中使用 TextView,在另一行中使用 TextFields,所以我使用这些方法:

- (void)textViewDidBeginEditing:(UITextView *)textView

    MyCustomTableController *itemControl = (MyCustomTableController *)self.owningController;
    [itemControl setEditRow:self];

- (void)textFieldDidBeginEditing:(UITextField *)textField

    MyCustomTableController *itemControl = (MyCustomTableController *)self.owningController;
    [itemControl setEditRow:self];

到目前为止,这工作得很好。

【讨论】:

以上是关于静态表视图 - 键盘隐藏的 UITextField的主要内容,如果未能解决你的问题,请参考以下文章

键盘隐藏视图(AutoLayout + StoryBoard)

acessoryView 内的 UITextField -- 清除按钮未检测到触摸

键盘隐藏另一个视图的文本字段动画

如何在点击时出现键盘时管理UITextField的高度?

滚动到包含某个 UITextField 的 UITableViewCell

添加子视图时iOS奇怪的键盘隐藏行为