关于ios 6:出现键盘时UITableView不滚动

UITableView doesn't scroll when keyboard appears

我在这里尝试了 Apple 的示例:

http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

但是,它似乎不起作用,所以我显然在此过程中遗漏了一些东西,只是不知道是什么。

我有一个 ViewController.h 包含:

1
2
3
4
5
6
7
8
9
10
@interface PreferencesViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, defaultLocationChoice, UITextFieldDelegate, UIScrollViewDelegate>

@property (nonatomic, retain) NSString *defaultLocation;
@property (nonatomic, retain) NSString *defaultTestType;
@property (nonatomic, assign) id <defaultLocationChoice> locationDelegate;
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, strong) IBOutlet UITextField *locationnameTextField;
@property (nonatomic, strong) IBOutlet UITextField *locationaddressTextField;
@property (strong, nonatomic) IBOutlet UITableView *scrollView;
@property (nonatomic, strong) IBOutlet UITextField *activeField;

.m文件里都有Synthesized。

我在 ViewController.m 中有 Apple 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
- (void)viewDidLoad
{
    NSUserDefaults *sharedPref = [NSUserDefaults standardUserDefaults];
    defaultLocation =[sharedPref stringForKey:@"defaultLocation"];
    defaultTestType =[sharedPref stringForKey:@"defaultTestType"];

    [self registerForKeyboardNotifications];


    self.navigationItem.title = @"Preferences";

    [super viewDidLoad];

}

- (void)registerForKeyboardNotifications

{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:)
 name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.

- (void)keyboardWasShown:(NSNotification*)aNotification

{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible

    // Your application might not need or want this behavior.

    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;

    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {

        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);

        [scrollView setContentOffset:scrollPoint animated:YES];
    }
}



// Called when the UIKeyboardWillHideNotification is sent

- (void)keyboardWillBeHidden:(NSNotification*)aNotification

{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField

{
    activeField = textField;
}



- (void)textFieldDidEndEditing:(UITextField *)textField

{
    activeField = nil;
}

包含 TextFields 的单元格在 CellForRowAtIndexPath 中处理如下(完整代码未显示):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  case 2:
            switch (indexPath.row) {
                case 0:

                    prefCell.textLabel.text = @"";
                    prefCell.accessoryType = UITableViewCellAccessoryNone;
                    prefCell.highlighted = NO;
                    locationnameTextField.frame = CGRectMake(5, 12, 300, 30);
                    locationnameTextField.font = [UIFont systemFontOfSize:13.0f];
                    locationnameTextField.placeholder = @"Enter location name i.e. New York, NY";
                    locationnameTextField.delegate = self;
                    locationnameTextField.returnKeyType = UIReturnKeyDone;
                    [prefCell.contentView addSubview:locationnameTextField];

                    break;
                case 1:
                    prefCell.textLabel.text = @"";
                    prefCell.accessoryType = UITableViewCellAccessoryNone;

                    locationaddressTextField.frame = CGRectMake(5, 12, 300, 30);
                     locationaddressTextField.font = [UIFont systemFontOfSize:13.0f];
                    locationaddressTextField.placeholder = @"Enter location address i.e. mcs.newyork.com";
                    locationaddressTextField.clearsOnBeginEditing = YES;
                    locationaddressTextField.delegate = self;
                    locationaddressTextField.returnKeyType = UIReturnKeyDone;

                    [prefCell.contentView addSubview:locationaddressTextField];

                    break;
            }

在运行应用程序时,键盘会弹出,但没有任何反应。

Apples 示例适用于 View,因此我在上面更改的唯一代码是 self.view.frameself.tableView.frame 无效。

我添加了 ScrollView 作为附加项,因为我没有。我的其他带有嵌入式 TableView 的 ViewController 不需要 ScrollView 来滚动。

层次结构如下:

enter

1
2
3
4
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
 [yourTextField resignFirstResponder];
}


既然找到了,我就用TPKeyboardAvoiding

它工作得很好,而且很容易设置:

  • 将 UIScrollView 添加到视图控制器的 xib
  • 将滚动视图的类设置为 TPKeyboardAvoidingScrollView(仍在 xib 中,通过
    身份检查员)
  • 将所有控件放在该滚动视图中

  • 当我注意到文本字段的超级视图时,我正在为同样的问题挠头。如果我是对的,那么您在 tableview 的单元格内有文本字段。

    现在,在您的 keyboardWasShown: 方法中,您正在检查活动文本字段是否隐藏在键盘下,如下所示:

    1
    2
    3
    4
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }

    if 条件在您的情况下永远不会成立。由于活动文本字段的超级视图是一个单元格,因此 activeField.frame.origin 将返回一个引用 UITableViewCell 的点,而不是引用您的 UIView.

    因此,您需要做的是检查包含活动文本字段的单元格是否隐藏在键盘下,如下所示:

    1
    2
    3
    4
    5
    6
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, cellForActiveField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, cellForActiveField.frame.origin.y-kbSize.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }

    要找到包含活动文本字段的单元格,您需要在 tableView:cellForIndexPath: 方法中设置文本字段的 tag 属性,然后在 textFieldDidBeginEditing: 方法中检查标记。

    更多细节,也可以参考这个问题。

    希望这会有所帮助。