使用iOS SDK:

我有一个带UITextFields的UIView,可以启动键盘。我需要它能够:

启动键盘后,允许滚动UIScrollView的内容以查看其他文本字段自动“跳转”(通过向上滚动)或缩短

我知道我需要一个UIScrollView。我已经尝试将UIView的类更改为UIScrollView,但仍然无法上下滚动文本框。

我需要UIView和UIScrollView吗?一个在另一个里面吗?

要自动滚动到活动文本字段,需要执行哪些操作?

理想情况下,尽可能多的组件设置将在Interface Builder中完成。我只想编写需要的代码。

注意:我使用的UIView(或UIScrollView)是由一个选项卡(UITabBar)启动的,它需要正常工作。


我正在添加滚动条,只为键盘出现时使用。尽管不需要它,但我觉得它提供了一个更好的界面,例如,用户可以滚动和更改文本框。

当键盘上下移动时,我可以改变UIScrollView的框架大小。我只是在使用:

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    //Keyboard becomes visible
    scrollView.frame = CGRectMake(scrollView.frame.origin.x,
                                  scrollView.frame.origin.y,
    scrollView.frame.size.width,
    scrollView.frame.size.height - 215 + 50);   // Resize
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
    // Keyboard will hide
    scrollView.frame = CGRectMake(scrollView.frame.origin.x,
                                  scrollView.frame.origin.y,
                                  scrollView.frame.size.width,
                                  scrollView.frame.size.height + 215 - 50); // Resize
}

然而,这不会自动“向上移动”或将可见区域中的下部文本字段居中,这是我真正想要的。


当前回答

这是我为特定布局想出的破解方案。此解决方案与Matt Gallagher的解决方案相似,即将一个部分滚动到视图中。我还是iPhone开发的新手,不熟悉布局的工作原理。因此,这个黑客。

我的实现需要支持在字段中单击时滚动,以及用户在键盘上选择下一个时滚动。

我有一个UIView,身高775。控件基本上以3人一组的方式分布在一个大的空间中。我最终得到了以下IB布局。

UIView -> UIScrollView -> [UI Components]

黑客来了

我将UIScrollView的高度设置为比实际布局(1250)大500个单位。然后,我创建了一个数组,其中包含我需要滚动到的绝对位置,以及一个基于IB标记号获取它们的简单函数。

static NSInteger stepRange[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 140, 140, 140, 410
};

NSInteger getScrollPos(NSInteger i) {
    if (i < TXT_FIELD_INDEX_MIN || i > TXT_FIELD_INDEX_MAX) {
        return 0 ;
    return stepRange[i] ;
}

现在,您需要做的就是在textFieldDidBeginEditing和textFieldShouldReturn中使用以下两行代码(如果要创建下一个字段导航,则使用后者)

CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;

一个例子。

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
    [self.scrollView setContentOffset:point animated:YES] ;
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField {

    NSInteger nextTag = textField.tag + 1;
    UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];

    if (nextResponder) {
        [nextResponder becomeFirstResponder];
        CGPoint point = CGPointMake(0, getScrollPos(nextTag)) ;
        [self.scrollView setContentOffset:point animated:YES] ;
    }
    else{
        [textField resignFirstResponder];
    }

    return YES ;
}

此方法不像其他方法那样“向后滚动”。这不是必需的。同样,这是一个相当“高大”的UIView,我没有时间学习内部布局引擎。

其他回答

首先,我为您的页面推荐一个更好的设计,这样就不需要滚动视图。如果您有许多文本字段,您仍然不必使用ScrollView,这只会使事情变得复杂。您只需在控制器原始视图的顶部添加一个容器UIView,然后将这些文本字段放在该视图上。当键盘显示或消失时,只需使用动画移动此容器视图。

刚找到这个类:

https://github.com/OliverLetterer/SLScrollViewKeyboardSupport

到目前为止,它在iPhone上运行得很好,包括动画和正确的偏移。

要使用它,只需添加到viewDidLoad:

self.support = [[SLScrollViewKeyboardSupport alloc] initWithScrollView:self.scrollView];

根据文档,从iOS 3.0开始,当有文本字段的在线编辑时,UITableViewController类会自动调整其表视图的大小并重新定位。我认为将文本字段放在UITableViewCell中是不够的,正如一些人所指出的那样。

从文档中:

表视图控制器支持表视图行的内联编辑;例如,如果行在编辑模式下嵌入了文本字段滚动虚拟键盘上方正在编辑的行显示。

-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField {

  [self slideUp];
   return YES;
}

-(BOOL) textFieldShouldEndEditing:(UITextField *)textField {

    [self slideDown];
   return YES;
}

#pragma mark - Slide Up and Down animation

- (void) slideUp {
    [UIView beginAnimations:nil context:nil];
    layoutView.frame = CGRectMake(0.0, -70.0, layoutView.frame.size.width, layoutView.frame.size.height);

    [UIView commitAnimations];
}


- (void) slideDown {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelay: 0.01]; 
    layoutView.frame = CGRectMake(0.0, 0.0, layoutView.frame.size.width, layoutView.frame.size.height);
    [UIView commitAnimations];
}

仅使用文本字段:

1a)使用界面生成器:选择所有文本字段=>编辑=>嵌入=>滚动视图

1b)在UIScrollView中手动嵌入文本字段,称为scrollView

2) 设置UITextFieldDelegate

3) 设置每个textField.delegate=self;(或在Interface Builder中建立连接)

4) 复制/粘贴:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
    [scrollView setContentOffset:scrollPoint animated:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [scrollView setContentOffset:CGPointZero animated:YES];
}