0
votes

My UIViewController splits to 2:

  1. UIView
  2. UITableView

I've added a footer view to table in order to hide the rest of the table. Since I cannot use static cells and also hide all bottom view of the table, I did it a bit tricky.

But the table view didn't scroll to top when I tap on my textfields correctly.

The keyboard hides the UITextField and doesn't scroll to correct point.

How can I fix it?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return 6;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{        
    NSString *identifier;

    if (indexPath.row == 0) identifier = @"cell_name";
    else if (indexPath.row == 1) identifier = @"cell_password";
    else if (indexPath.row == 2) identifier = @"cell_password_verify";
    else if (indexPath.row == 3) identifier = @"cell_email";
    else if (indexPath.row == 4) identifier = @"cell_cellphone";
    else if (indexPath.row == 5) identifier = @"cell_social";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
    if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];

    return cell;
}

- (void)configureUI
{
    UIView *tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 1)];
    tableFooterView.backgroundColor = [UIColor whiteColor];
    self.tableView.tableFooterView = tableFooterView;
    tableFooterView.backgroundColor = [UIColor whiteColor];
    self.tableView.tableFooterView = tableFooterView;

    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

enter image description here

enter image description here

UPDATE:

Problem was, scroll view cannot scroll because tableFooterView is too short, then I modified my code. Basically,@Roger Nolan right, I also added the following code and now it works perfect:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    UITableViewCell *cell = (UITableViewCell *)textField.superview.superview.superview;
    [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)registerObservers
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidHide:)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
}

- (void)keyboardDidShow:(NSNotification *)notification
{
    CGFloat keyboardHeight = [CoreGraphicsHandler keyboardFramFromNotification:notification].size.height;

     UIView *tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), keyboardHeight)];
     tableFooterView.backgroundColor = [UIColor whiteColor];
     self.tableView.tableFooterView = tableFooterView;
}

- (void)keyboardDidHide:(NSNotification *)notification
{

    UIView *tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 1)];
    tableFooterView.backgroundColor = [UIColor whiteColor];
    self.tableView.tableFooterView = tableFooterView;
}
2
When the keyboard shows, could you modify the margin of the top UIView? Maybe I'm not understanding the question correctly.Dehli
I edited my question.Idan Moshe
I've run into this exact thing and I have just the solution, but I'll have to wait to share it til I get home tonight.Gutblender
possible duplicate of UITableView and keyboard scrolling issueRog
Looks like you are implementing a static table view with dynamic delegate methods. You should make that a static table view. In IB, select the table view and it is the top item in the property editor.Rog

2 Answers

1
votes

You need to make the controller a delegate of your text fields and then send the tableview scrollToRowAtIndexPath:atScrollPosition: animated:

See this exact dupe: Making a UITableView scroll when text field is selected

0
votes

I had a similar problem and, as suggested by Idan Moshe in the update, I solved inserting a footerView in my tableView. The solution in Swift 4:

func registerObservers(){

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil);
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: NSNotification.Name.UIKeyboardDidHide, object: nil);

}

@objc func keyboardDidShow(_ notification: Notification) {

    DispatchQueue.main.async {

        if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
            let keyboardHeight = keyboardFrame.cgRectValue.height;
            let tableFooterView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: keyboardHeight))
            self.tableView.tableFooterView = tableFooterView;
        }
    }
}

@objc func keyboardDidHide(_ notification: Notification) {

    DispatchQueue.main.async {

        let tableFooterView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 1));
        self.tableView.tableFooterView = tableFooterView;
    }
}

func textFieldDidBeginEditing(_ textField: UITextField) {

    let cell = self.selectedTExtField?.superview?.superview;
    if let idxPath = self.tableView.indexPath(for: cell){
        self.tableView.scrollToRow(at: idxPath, at: .top, animated: true);
    }
    else{
        print("Error: index path not found");
    }
}