经过大量的试验和错误,我放弃了,并提出了这个问题。我见过很多人有类似的问题,但不能得到所有的答案工作正确。
我有一个由自定义单元格组成的UITableView。单元格由相邻的5个文本字段组成(有点像网格)。
当我试图滚动和编辑UITableView底部的单元格时,我不能设法让我的单元格正确地定位在键盘上方。
我看到过很多关于改变视图大小的回答……但到目前为止,没有一种效果很好。
谁能用一个具体的代码示例来阐明这样做的“正确”方式?
经过大量的试验和错误,我放弃了,并提出了这个问题。我见过很多人有类似的问题,但不能得到所有的答案工作正确。
我有一个由自定义单元格组成的UITableView。单元格由相邻的5个文本字段组成(有点像网格)。
当我试图滚动和编辑UITableView底部的单元格时,我不能设法让我的单元格正确地定位在键盘上方。
我看到过很多关于改变视图大小的回答……但到目前为止,没有一种效果很好。
谁能用一个具体的代码示例来阐明这样做的“正确”方式?
当前回答
我可能错过了这一点,因为我没有阅读整篇文章,但我想到的似乎很简单。我并没有在所有情况下进行测试,但它看起来应该工作得很好。
简单地根据键盘的高度调整tableview的contentInset,然后将单元格滚动到底部:
- (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);
self.myTableView.contentInset = contentInsets;
self.myTableView.scrollIndicatorInsets = contentInsets;
[self.myTableView scrollToRowAtIndexPath:self.currentField.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
当然
- (void)keyboardWasHidden:(NSNotification *)aNotification
{
[UIView animateWithDuration:.3 animations:^(void)
{
self.myTableView.contentInset = UIEdgeInsetsZero;
self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}];
}
这是不是太简单了?我遗漏了什么吗?到目前为止,它对我来说还不错,但就像我说的,我还没有把它经过折腾……
其他回答
因为你在一个表格中有文本字段,最好的方法是调整表格的大小——你需要设置tableView.frame的高度比键盘的大小小(我认为大约165像素),然后当键盘被关闭时再次展开它。
如果你不想让用户滚动,你也可以选择在那个时候禁用tableView的用户交互。
我想我已经想出了与苹果应用程序行为相匹配的解决方案。
首先,在viewWillAppear:订阅键盘通知,这样你就知道什么时候键盘会显示和隐藏,系统会告诉你键盘的大小,但不要忘记在viewWillDisappear:中取消注册。
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
实现类似于下面的方法,以便在键盘显示时调整tableView的大小以匹配可见区域。这里我单独跟踪键盘的状态,所以我可以自己选择何时将tableView设置为全高度,因为你在每个字段更改时都会收到这些通知。不要忘记实现keyboardWillHide:并选择适当的地方来修复你的tableView大小。
-(void) keyboardWillShow:(NSNotification *)note
{
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
keyboardHeight = keyboardBounds.size.height;
if (keyboardIsShowing == NO)
{
keyboardIsShowing = YES;
CGRect frame = self.view.frame;
frame.size.height -= keyboardHeight;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3f];
self.view.frame = frame;
[UIView commitAnimations];
}
}
现在这是滚动位,我们先计算出一些大小,然后我们看到我们在可见区域中的位置,并设置我们想要滚动的矩形,根据它在视图中的位置,将它设置为文本字段中间上方或下方的半视图。在本例中,我们有一个UITextFields数组和一个用于跟踪它们的enum,因此用rowHeight乘以行号就得到了这个外部视图中帧的实际偏移量。
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
CGRect frame = textField.frame;
CGFloat rowHeight = self.tableView.rowHeight;
if (textField == textFields[CELL_FIELD_ONE])
{
frame.origin.y += rowHeight * CELL_FIELD_ONE;
}
else if (textField == textFields[CELL_FIELD_TWO])
{
frame.origin.y += rowHeight * CELL_FIELD_TWO;
}
else if (textField == textFields[CELL_FIELD_THREE])
{
frame.origin.y += rowHeight * CELL_FIELD_THREE;
}
else if (textField == textFields[CELL_FIELD_FOUR])
{
frame.origin.y += rowHeight * CELL_FIELD_FOUR;
}
CGFloat viewHeight = self.tableView.frame.size.height;
CGFloat halfHeight = viewHeight / 2;
CGFloat midpoint = frame.origin.y + (textField.frame.size.height / 2);
if (midpoint < halfHeight)
{
frame.origin.y = 0;
frame.size.height = midpoint;
}
else
{
frame.origin.y = midpoint;
frame.size.height = midpoint;
}
[self.tableView scrollRectToVisible:frame animated:YES];
}
这似乎工作得很好。
以下是我如何做到这一点的,这是Sam Ho和Marcel W的回答,以及我自己对蹩脚代码的一些错误修复。我用的是UITableViewController。当键盘显示时,表格现在可以正确地调整大小。
1)在viewDidLoad我添加:
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
2)我忘记在viewWillAppear和awakeFromNib中调用超等价物。我把这些加回来了。
我可能错过了这一点,因为我没有阅读整篇文章,但我想到的似乎很简单。我并没有在所有情况下进行测试,但它看起来应该工作得很好。
简单地根据键盘的高度调整tableview的contentInset,然后将单元格滚动到底部:
- (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);
self.myTableView.contentInset = contentInsets;
self.myTableView.scrollIndicatorInsets = contentInsets;
[self.myTableView scrollToRowAtIndexPath:self.currentField.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
当然
- (void)keyboardWasHidden:(NSNotification *)aNotification
{
[UIView animateWithDuration:.3 animations:^(void)
{
self.myTableView.contentInset = UIEdgeInsetsZero;
self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}];
}
这是不是太简单了?我遗漏了什么吗?到目前为止,它对我来说还不错,但就像我说的,我还没有把它经过折腾……
我尝试了几乎相同的方法,并提出了一个更简单、更小的代码。 我创建了一个IBOutlet iTextView,并与IB中的UITextView相关联。
-(void)keyboardWillShow:(NSNotification *)notification
{
NSLog(@"Keyboard");
CGRect keyFrame = [[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];
[UIView beginAnimations:@"resize view" context:nil];
[UIView setAnimationCurve:1];
[UIView setAnimationDuration:1.0];
CGRect frame = iTableView.frame;
frame.size.height = frame.size.height - keyFrame.size.height;
iTableView.frame = frame;
[iTableView scrollRectToVisible:frame animated:YES];
[UIView commitAnimations];
}