【问题标题】:Scroll Group tableView when keyboard appears出现键盘时滚动 Group tableView
【发布时间】:2012-08-25 12:09:10
【问题描述】:

我正在尝试创建一个视图,用户可以在其中输入他的信息(姓名、电子邮件、简历...)。

为此,我使用了一个包含 5 个部分 (0..4) 的组表视图,每个部分都有一个单元格,里面有一个 UITextField(除了第 4 部分中的单元格里面有一个 UITextView) .

当用户点击其中一个 textFields/textView 时,会出现键盘,并且单元格(带有选定的 textField/textView)滚动到键盘正上方的位置。

我的问题是第 4 节的 textView,当键盘出现时,它会以某种方式自动滚动单元格以使其可见,但不完全位于正确的位置(文本视图的一半隐藏在键盘后面)。
当我尝试自己进行滚动时(在键盘完成动画后),我得到了一个难看的 textView 反弹。

看起来难看的反弹的原因是当键盘出现时textView自动滚动+我的滚动。这种(自动滚动)行为仅发生在 textView 中,例如,如果我在第 4 节中使用 textField 而不是 textView,它不会自动滚动。

所以问题是:如何才能将 textView 平滑地滚动到正确的位置?

这是我的代码:

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 5;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

    switch (indexPath.section) {
        case 0:
            [cell.contentView addSubview:self.textField1];
            break;
        case 1:
            [cell.contentView addSubview:self.textField2];
            break;
        case 2:
            [cell.contentView addSubview:self.textField3];
            break;
        case 3:
            [cell.contentView addSubview:self.textField4];
            break;
        case 4:
            // this is the text view
            [cell.contentView addSubview:self.textView];
            break;
        default:
            break;
    }

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}



#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    self.activeResponder = textField;
    return YES;
}

#pragma mark - UITextViewDelegate

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
    self.activeResponder = textView;
    return YES;
}

- (void)keyboardWillShow:(NSNotification*)notification {
    NSLog(@"keyboard show");
    CGFloat animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    CGRect tableViewFrame = self.tableView.frame;
    tableViewFrame.size.height -= keyboardFrame.size.height;

    [UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.tableView.frame = tableViewFrame;
    } completion:^(BOOL finished) {
        [self scrollToActiveResponder];
    }];
}

- (void)keyboardWillHide:(NSNotification*)notification {
    NSLog(@"keyboard hide");
    CGFloat animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    CGRect tableViewFrame = self.tableView.frame;
    tableViewFrame.size.height += keyboardFrame.size.height;

    [UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.tableView.frame = tableViewFrame;
    } completion:^(BOOL finished) {
    }];
}     

- (NSIndexPath *)indexPathForActiveResponder {
        NSIndexPath *indexPath = nil;
        if (self.activeResponder == self.textField1) {
            indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        }
        else if (self.activeResponder == self.textField2) {
            indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
        }
        else if (self.activeResponder == self.textField3) {
            indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
        }
        else if (self.activeResponder == self.textField4) {
            indexPath = [NSIndexPath indexPathForRow:0 inSection:3];
        }
        else if (self.activeResponder == self.textView) {
            indexPath = [NSIndexPath indexPathForRow:0 inSection:4];
        }
        return indexPath;
    } 

- (void)scrollToActiveResponder {
    NSIndexPath *activeResponderIndexPath = [self indexPathForActiveResponder];
    if (activeResponderIndexPath) {
        [self.tableView scrollToRowAtIndexPath:activeResponderIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
    }
}

【问题讨论】:

    标签: iphone objective-c ios uitableview uitextview


    【解决方案1】:

    我会尝试这样的事情:

    .h

    @interface YourViewController : UIViewController <UITextViewDelegate>
    

    .m

    //Set delegate to your textView
    textView.delegate = self
    
    #pragma mark - TextView Delegate
    //TextView Became First Responder
    - (void)textViewDidBeginEditing:(UITextView *)textView{
    
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:4];
    
        // Other way to get the IndexPath
        //NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[textView superview] superview]];
    
        CGRect frame = [self.tableView rectForRowAtIndexPath:indexPath];
    
        //It only works for Portrait iPhone
        CGFloat keyboardHeight = 216.0f;
    
        CGPoint offset = CGPointMake(0, self.view.frame.size.height - keyboardHeight - frame.size.height - frame.origin.y);
        [self.tableView setContentOffset:offset animated:YES];
    
    }
    

    我没有对其进行测试,但这是我尝试解决此问题的方法。您可以在此处找到有关如何计算键盘大小的更多信息:(http://www.idev101.com/code/User_Interface/keyboard.html)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 2015-02-02
      • 2013-02-25
      • 1970-01-01
      • 2016-12-17
      • 2014-08-23
      相关资源
      最近更新 更多