在编辑第一个UITextField时,如何将UITableView滚动到第二个UITextField?

时间:2013-08-02 18:08:05

标签: ios objective-c uitableview

我们假设我们有一个应用程序的登录屏幕。登录屏幕实现UITableViewController,其中包含UITableViewUITableView有1个部分,该部分包含两个单元格(请参阅下面的故事板)。

Storyboard

当前行为

当用户开始编辑电子邮件字段时 - 使用占位符输入您的电子邮件 - 键盘与密码字段重叠 - 使用占位符输入您的密码。

Password field is not visible Password field is visible when editing password

所需行为

当用户开始编辑电子邮件字段时,键盘应与 字段重叠,键盘应位于下方两个字段。

尝试解决方案

我试图在我的LoginFormController : UITableViewController中使用以下内容强制UITableView滚动到适当的位置,但无济于事:

-(BOOL) textFieldSHouldBeginEditing:(RCTextField *)textField
{
    [[self.view viewWithTag:textField.tag+1] becomeFirstResponder];

    // get the scroll index path of the last row in the first section
    NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];

    // scroll the view there
    [[self tableView] scrollToRowAtIndexPath:scrollIndexPath
                            atScrollPosition:UITableViewScrollPositionBottom animated:YES];

    return YES;
}

我的LoginFormController : UITableViewController界面:

//
//  LoginFormController.h
//  Zealoushacker
//
//  Created by Alex Notov on 7/31/13.
//  Copyright (c) 2013 Zealoushacker, Inc. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface LoginFormController : UITableViewController <UITextFieldDelegate>

@end

LoginFormController当然引用了tableView

4 个答案:

答案 0 :(得分:1)

您可以尝试将TPKeyboardAvoiding添加到项目中

TPKeyboardAvoiding - 一种插入式通用解决方案,用于在iOS中将文本字段移出键盘。

要与UITableViewController classes一起使用,请将 TPKeyboardAvoidingTableView.m TPKeyboardAvoidingTableView.h 放入您的项目中,并将您的UITableView设为TPKeyboardAvoidingTableView XIB。

检查Sample

答案 1 :(得分:1)

scrollToRowAtIndexPath无法正常工作的原因是键盘在该点没有占用任何空间,因此当您告诉表格视图使这些单元格可见时,它们已经是。

你想要做的是调用setContentOffset并传入文本字段的原点减去一个偏移量(将字段向下移动一点),就像这样(尽管你可能想要为它设置动画)与setContentOffset:animated:):

-(BOOL) textFieldSHouldBeginEditing:(RCTextField *)textField
{
    CGRect frame = [textField frame];
    [[self tableView] setContentOffset:CGPointMake(frame.origin.x, frame.origin.y - 5.0f)];
    return MAYBE;
}

答案 2 :(得分:1)

这很难看,因为我没有花时间像@Turch一样精致......我只是粗略地使用数字100但是随意改进它......整体而言它是有效的。

-(BOOL) textFieldShouldBeginEditing:(RCTextField *)textField
{
    // ***HACK*** here part 1
    if (textField == self.email) {
        CGRect frame = self.tableView.frame;
        float moveUpTo = self.tableView.frame.origin.y - 100.0f;
        if (self.tableView.frame.origin.y == 0.0f) {
            frame.origin.y = moveUpTo;
            self.tableView.frame = frame;
        }
    }
    return YES;
}

-(BOOL) textFieldShouldReturn:(UITextField *)textField {
    ...
        [textField resignFirstResponder];

        // ***HACK*** here part 2
        CGRect frame = self.tableView.frame;
        float moveDownTo = self.tableView.frame.origin.y + 100.0f;
        if (self.tableView.frame.origin.y != 0.0f) {
            frame.origin.y = moveDownTo;
            self.tableView.frame = frame;
        }

        return YES;
    }
}

答案 3 :(得分:0)

在考虑了所有答案之后,我根据下面的内容提出了自己的答案,我发现它非常干净。

我已经实施了一个类别LoginFormController+Scrolling.h

//
//  LoginFormController+Scrolling.h
//  Zealoushacker
//
//  Created by Alex Notov on 8/2/13.
//  Copyright (c) 2013 Zealoushacker, Inc. All rights reserved.
//

#import "LoginFormController.h"

typedef enum {
    UITableViewBottom = 0,
    UITableViewTop = 1
} UITableViewPosition ;

@interface LoginFormController (Scrolling)
-(void)moveLoginFormToTableView:(UITableViewPosition)p;
@end

及其实施LoginFormController+Scrolling.m

//
//  LoginFormController+Scrolling.m
//  Zealoushacker
//
//  Created by Alex Notov on 8/2/13.
//  Copyright (c) 2013 Zealoushacker, Inc. All rights reserved.
//

#import "LoginFormController+Scrolling.h"

@implementation LoginFormController (Scrolling)
- (float)heightOfAllCells {
    float height = 0;
    for (UIView *subview in self.tableView.subviews)
    {
        if ([subview isKindOfClass:[UITableViewCell self]])
        {
            height += subview.frame.size.height;
        }
    }
    return height;
}

-(void)moveLoginFormToTableView:(UITableViewPosition)p
{
    // this is adapted from:
    // http://stackoverflow.com/questions/18023457/how-may-i-scroll-a-uitableview-to-the-second-uitextfield-when-the-first-uitextfi/18023825
    CGRect frame = self.tableView.frame;

    if (p == UITableViewBottom && self.tableView.frame.origin.y == 0.0f) {
        frame.origin.y -= [self heightOfAllCells];
    } else if (p == UITableViewTop && self.tableView.frame.origin.y != 0.0f) {
        frame.origin.y += [self heightOfAllCells];

    }
    self.tableView.frame = frame;
}
@end

然后,在我的LoginFormController.m中,我可以简单地致电[self moveLoginFormToTableView:UITableViewBottom];滚动到UITableView的底部,无论它有多少UITableViewCell个组件,反之亦然致电[self moveLoginFormToTableView:UITableViewTop];将其滚动回原来的位置。