静态表视图 - 键盘隐藏的 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 -- 清除按钮未检测到触摸