经过大量的试验和错误,我放弃了,并提出了这个问题。我见过很多人有类似的问题,但不能得到所有的答案工作正确。
我有一个由自定义单元格组成的UITableView。单元格由相邻的5个文本字段组成(有点像网格)。
当我试图滚动和编辑UITableView底部的单元格时,我不能设法让我的单元格正确地定位在键盘上方。
我看到过很多关于改变视图大小的回答……但到目前为止,没有一种效果很好。
谁能用一个具体的代码示例来阐明这样做的“正确”方式?
经过大量的试验和错误,我放弃了,并提出了这个问题。我见过很多人有类似的问题,但不能得到所有的答案工作正确。
我有一个由自定义单元格组成的UITableView。单元格由相邻的5个文本字段组成(有点像网格)。
当我试图滚动和编辑UITableView底部的单元格时,我不能设法让我的单元格正确地定位在键盘上方。
我看到过很多关于改变视图大小的回答……但到目前为止,没有一种效果很好。
谁能用一个具体的代码示例来阐明这样做的“正确”方式?
当前回答
// scroll tableview so content ends at the middle of the tableview (out of the way of the keyboard)
CGPoint newContentOffset = CGPointMake(0, [self.tableView contentSize].height - (self.tableView.bounds.size.height / 2));
[self.tableView setContentOffset:newContentOffset animated:YES];
其他回答
一个更加流线型的解决方案。它滑入UITextField委托方法,所以它不需要搞砸/ UIKeyboard通知。
实现注意事项:
kSettingsRowHeight——UITableViewCell的高度。
offsetTarget和offsetThreshold基于kSettingsRowHeight。如果使用不同的行高,则将这些值设置为point的y属性。[alt:以不同的方式计算行偏移量。]
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat offsetTarget = 113.0f; // 3rd row
CGFloat offsetThreshold = 248.0f; // 6th row (i.e. 2nd-to-last row)
CGPoint point = [self.tableView convertPoint:CGPointZero fromView:textField];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect frame = self.tableView.frame;
if (point.y > offsetThreshold) {
self.tableView.frame = CGRectMake(0.0f,
offsetTarget - point.y + kSettingsRowHeight,
frame.size.width,
frame.size.height);
} else if (point.y > offsetTarget) {
self.tableView.frame = CGRectMake(0.0f,
offsetTarget - point.y,
frame.size.width,
frame.size.height);
} else {
self.tableView.frame = CGRectMake(0.0f,
0.0f,
frame.size.width,
frame.size.height);
}
[UIView commitAnimations];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect frame = self.tableView.frame;
self.tableView.frame = CGRectMake(0.0f,
0.0f,
frame.size.width,
frame.size.height);
[UIView commitAnimations];
return YES;
}
我认为最好的方法是通过UITableViewController。
如果你想在UIViewController中创建一个UITableView,只需要用一个嵌入的UITableViewController创建一个ContentView,并在UIViewController的viedDidLoad中放入以下代码行:
self.tableView = ((UITableViewController*)self.childViewControllers[0]).tableView;
self.tableView.delegate = self;
self.tableView.dataSource = self;
容易,)
看看我的版本:)
- (void)keyboardWasShown:(NSNotification *)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = cellSelected.superview.frame;
bkgndRect.size.height += kbSize.height;
[cellSelected.superview setFrame:bkgndRect];
[tableView setContentOffset:CGPointMake(0.0, cellSelected.frame.origin.y-kbSize.height) animated:YES];
}
- (void)keyboardWasHidden:(NSNotification *)aNotification
{
[tableView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];
}
我刚刚发现另一个bug时使用UITableViewController。当键盘出现时,它不会自动滚动。我注意到这是因为contentInsetAdjustmentBehavior = .never在UITableView上。
键盘通知可以工作,但苹果的示例代码假设滚动视图是窗口的根视图。通常情况并非如此。您必须补偿标签栏等,以获得正确的偏移量。
这比听起来容易。下面是我在UITableViewController中使用的代码。它有两个实例变量,hiddenRect和keyboardshow。
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
if (keyboardShown)
return;
NSDictionary* info = [aNotification userInfo];
// Get the frame of the keyboard.
NSValue *centerValue = [info objectForKey:UIKeyboardCenterEndUserInfoKey];
NSValue *boundsValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGPoint keyboardCenter = [centerValue CGPointValue];
CGRect keyboardBounds = [boundsValue CGRectValue];
CGPoint keyboardOrigin = CGPointMake(keyboardCenter.x - keyboardBounds.size.width / 2.0,
keyboardCenter.y - keyboardBounds.size.height / 2.0);
CGRect keyboardScreenFrame = { keyboardOrigin, keyboardBounds.size };
// Resize the scroll view.
UIScrollView *scrollView = (UIScrollView *) self.tableView;
CGRect viewFrame = scrollView.frame;
CGRect keyboardFrame = [scrollView.superview convertRect:keyboardScreenFrame fromView:nil];
hiddenRect = CGRectIntersection(viewFrame, keyboardFrame);
CGRect remainder, slice;
CGRectDivide(viewFrame, &slice, &remainder, CGRectGetHeight(hiddenRect), CGRectMaxYEdge);
scrollView.frame = remainder;
// Scroll the active text field into view.
CGRect textFieldRect = [/* selected cell */ frame];
[scrollView scrollRectToVisible:textFieldRect animated:YES];
keyboardShown = YES;
}
// Called when the UIKeyboardDidHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
// Reset the height of the scroll view to its original value
UIScrollView *scrollView = (UIScrollView *) self.tableView;
CGRect viewFrame = [scrollView frame];
scrollView.frame = CGRectUnion(viewFrame, hiddenRect);
keyboardShown = NO;
}