You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何禁用TPKeyboardAvoidingTableView编辑TextField时的自动滚动

搞定TPKeyboardAvoidingTableView编辑最后一个Cell时自动滚顶的问题

嘿,我看你遇上了个挺闹心的问题:用TPKeyboardAvoidingTableView的时候,编辑最后一个单元格里的TextField,表格居然自动滚到顶部,根本没法好好输入。结合你贴的代码,我给你整理了几个靠谱的解决思路:

1. 先把多余的beginUpdates删掉,直接更新Cell内容

你代码里调用了[self.tableHSEMonthlyReport beginUpdates],但你只是更新现有单元格的总计标签,又没增删移动行,这个调用反而会触发表格重新计算布局,很可能就是它搞乱了滚动位置。直接去掉它,再加上保存恢复滚动位置的逻辑就行:

dispatch_async(dispatch_get_main_queue(), ^(void){
    // 先把当前的滚动位置存下来
    CGPoint currentOffset = self.tableHSEMonthlyReport.contentOffset;
    
    NSIndexPath* indexPath = [NSIndexPath indexPathForRow:txtIndPath.row inSection:txtIndPath.section];
    HSEMonthlyPerformanceTableViewCell *cell = [self.tableHSEMonthlyReport cellForRowAtIndexPath:indexPath];
    if (cell) {
        // 这里换成你实际计算总分的逻辑哈
        CGFloat score1 = [[((HSEMonthlyGeneralQuestion*)arrayGeneralQuestions[txtIndPath.row]).score1 floatValue];
        CGFloat score3 = [[((HSEMonthlyGeneralQuestion*)arrayGeneralQuestions[txtIndPath.row]).score3 floatValue];
        cell.lblTotal.text = [NSString stringWithFormat:@"%.2f", score1 + score3];
    }
    
    // 强制把滚动位置拉回之前的地方,不让它乱跑
    [self.tableHSEMonthlyReport setContentOffset:currentOffset animated:NO];
});

2. 实在不行,就临时管住TPKeyboardAvoiding的自动滚动

如果上面的方法还压不住,那可能是TPKeyboardAvoiding自带的键盘监听逻辑在捣乱。你可以在开始编辑的时候记好当前位置,等键盘弹出来的时候强行把表格拉回去:

首先在你的ViewController里加个变量存编辑时的滚动位置和当前编辑的TextField:

@property (nonatomic, assign) CGPoint editingContentOffset;
@property (nonatomic, weak) UITextField *activeTextField;

然后在textFieldDidBeginEditing:里记录位置和当前TextField:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    self.editingContentOffset = self.tableHSEMonthlyReport.contentOffset;
    self.activeTextField = textField;
}

接着监听键盘弹出事件,只在编辑最后一个Cell的时候强制恢复位置:

// 记得在viewDidLoad里加监听
- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    // 先找到当前编辑的Cell的位置
    CGPoint textFieldPoint = [self.activeTextField convertPoint:CGPointZero toView:self.tableHSEMonthlyReport];
    NSIndexPath *txtIndPath = [self.tableHSEMonthlyReport indexPathForRowAtPoint:textFieldPoint];
    // 只有编辑最后一个Cell的时候才强制拉回位置
    if (txtIndPath.row == arrayGeneralQuestions.count - 1) {
        [self.tableHSEMonthlyReport setContentOffset:self.editingContentOffset animated:NO];
    }
}

// 别忘了在dealloc里移除监听,避免内存泄漏
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

3. 顺便检查下数据源的线程安全

你在后台线程修改了arrayMonthlyGeneralQustion和arrayGeneralQuestions,虽然replaceObjectAtIndex:是原子操作,但如果其他地方也在访问这两个数组,可能会导致数据乱掉,间接让表格布局出问题。可以加个串行队列把数据源操作包起来,确保线程安全:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    // 创建一个串行队列,所有数据源操作都走这个队列
    static dispatch_queue_t dataQueue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dataQueue = dispatch_queue_create("com.yourApp.hseDataQueue", DISPATCH_QUEUE_SERIAL);
    });
    
    dispatch_sync(dataQueue, ^{
        [[HSEAppData appData].arrayMonthlyGeneralQustion replaceObjectAtIndex:txtIndPath.row withObject:dic];
        [arrayGeneralQuestions replaceObjectAtIndex:txtIndPath.row withObject:question];
    });
    
    // 主线程更新UI的代码...
});

小提醒

另外你可以检查下Cell的高度计算逻辑,确保它是固定的或者不会在编辑时突然变化,高度跳变也会导致表格滚动异常哦。

内容的提问来源于stack exchange,提问作者Manju Sreejith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:53:38