0

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

故事板

当前行为

当用户开始编辑电子邮件字段时 - 使用占位符 ENTER YOUR EMAIL - 键盘与密码字段重叠 - 使用占位符 ENTER YOUR 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

4 回答 4

1

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

TPKeyboardAvoiding - 在 iOS 中将文本字段移出键盘的嵌入式通用解决方案。

与 一起使用UITableViewController classes,拖放TPKeyboardAvoidingTableView.mTPKeyboardAvoidingTableView.h您的项目中,并使您的 UITableView 成为 xib 中的 TPKeyboardAvoidingTableView。

检查样品

于 2013-08-02T18:14:23.003 回答
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;
}
于 2013-08-02T18:32:16.057 回答
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;
    }
}
于 2013-08-02T19:43:41.507 回答
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

然后,在 my 中LoginFormController.m,我可以简单地调用[self moveLoginFormToTableView:UITableViewBottom];以滚动到 底部UITableView,而不管它有多少UITableViewCell组件,并反过来调用[self moveLoginFormToTableView:UITableViewTop];以将其滚动回原来的位置。

于 2013-08-02T22:59:07.503 回答