iPhone:滚动表格视图单元格可见自定义键盘对齐工具栏上方?

Tim*_*Tim 6 iphone user-interface scroll objective-c uitableview

在过去的几天里,我一直在问一个问题,那就是让自定义工具栏与iPhone键盘顶部对齐的应用程序.我正在使用Josh在这个问题中描述的方法; 基本上,我让视图控制器监听UIKeyboardWillShowNotification并根据需要添加工具栏.

视图控制器本身管理一个表视图,其单元格都包含UITextField.显示的键盘和工具栏正在编辑这些文本字段.我仍然遇到的唯一问题是:当键盘和工具栏出现在距离桌子大约一半的单元格时,它会滚动到键盘上方,但不会在工具栏上方.

单元格和文本字段仍可编辑,但大约一半的单元格隐藏在工具栏下.如果我消失工具栏(不要将其添加到通知响应器中),整个单元格将变为可见,但显然我将丢失工具栏提供的功能.

有没有办法更改文本字段滚动到的位置?我尝试过使用UITableView方法scrollToRowAtIndexPath:atScrollPosition:animated:,但是当切换到几个单元格时,它往往会产生奇怪的结果.

将表格视图单元格滚动到自定义键盘工具栏上方的可见位置的最佳方法是什么?

mmc*_*mmc 17

我完全按照你在我的应用中描述的内容.这是我使用的代码,逐字逐句.这是非常好的动画,似乎工作得非常好.

两个免责声明:

  1. 我将parentView作为自定义初始化的一部分传递.
  2. 我没有写这个代码,我不赞成它.我是从Matt Gallagher真正精彩的博客Cocoa With Love那里得到的.

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
// adjust this following value to account for the height of your toolbar, too
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;


- (void)textFieldDidEndEditing:(UITextField *)textField
{
  CGRect viewFrame = self.parentView.frame;
  viewFrame.origin.y += animatedDistance;

  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationBeginsFromCurrentState:YES];
  [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

  [self.parentView setFrame:viewFrame];

  [UIView commitAnimations];
}

- (void) textFieldDidBeginEditing:(UITextField*) textField {
  CGRect textFieldRect = [self.parentView.window convertRect:textField.bounds fromView:textField];
  CGRect viewRect = [self.parentView.window convertRect:self.parentView.bounds fromView:self.parentView];
  CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
  CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
  CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
  CGFloat heightFraction = numerator / denominator;

  if (heightFraction < 0.0) {
    heightFraction = 0.0;
  }else if (heightFraction > 1.0) {
    heightFraction = 1.0;
  }

  animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);

  CGRect viewFrame = self.parentView.frame;
  viewFrame.origin.y -= animatedDistance;

  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationBeginsFromCurrentState:YES];
  [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

  [self.parentView setFrame:viewFrame];

  [UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)


val*_*ine 6

假设您知道将在键盘上方显示的NSIndexPath,您可以使用以下快速而干净的方法:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    UITableViewCell *aCell = [myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]];
    CGSize cellSize = aCell.frame.size;
    [myTableView setContentOffset:CGPointMake(0, cellSize.height*6) animated:YES];
}       

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
                       atScrollPosition:UITableViewScrollPositionTop 
                               animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

由于UITableView继承自UIScrollView,因此您可以调整contentOffset属性以反映您感兴趣的行可见性.

DidEndEditing方法中,您必须恢复原始滚动位置.这是通过标准scrollToRowAtIndexPath:atScrollPosition:动画调用实现的.