Closed YearRen closed 3 years ago
遇到了相同的问题 请问老哥解决了吗
没有:(
Bug 解析:
先明确 UITableView 的2个系统默认特性:
本 issue 描述的 bug 可以理解为上述两种情况叠加后,系统对 contentSize 的计算产生了偏差,导致出现多余的 contentSize.height(例如 issue 内的 Demo,即便只有一行 cell,理论上 contentSize 是准确的,因为所有 cell 都可视,但此时系统就会算出来一个错误的 contentSize.height),当 estimatedRowHeight 与 rowHeight 相差越大时,这个多余的 contentSize.height 就越大,bug 就越明显。
系统出现这个错误的具体原因未明,QMUI 仅针对现象给出修补的方案:
tableView.estimatedRowHeight = 0
关闭它,从而规避这个 bug。
// [UIKit Bug] 将 UISearchBar 作为 tableHeaderView 使用的 UITableView,如果同时设置了 estimatedRowHeight,则 contentSize 会错乱,导致滚动异常
// https://github.com/Tencent/QMUI_iOS/issues/1161
void (^fixBugOfTableViewContentSize)(UITableView *) = ^void(UITableView *tableView) {
BOOL estimatesRowHeight = NO;
[tableView qmui_performSelector:NSSelectorFromString(@"_estimatesRowHeights") withPrimitiveReturnValue:&estimatesRowHeight];
if (estimatesRowHeight && [tableView.tableHeaderView isKindOfClass:UISearchBar.class]) {
[tableView performSelector:NSSelectorFromString(@"_updateContentSize")];
}
};
if (@available(iOS 11.0, )) { / - (void) _coalesceContentSizeUpdateWithDelta:(double)arg1; (0x7fff248dbcaf) / OverrideImplementation([UITableView class], NSSelectorFromString(@"_coalesceContentSizeUpdateWithDelta:"), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) { return ^(UITableView selfObject, CGFloat firstArgv) {
// call super
void (*originSelectorIMP)(id, SEL, CGFloat);
originSelectorIMP = (void (*)(id, SEL, CGFloat))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, firstArgv);
if (fixBugOfTableViewContentSize) {
fixBugOfTableViewContentSize(selfObject);
}
};
});
} else { / - (void)_applyContentSizeDeltaForEstimatedHeightAdjustments:(double)arg1; (0x106efad91) / OverrideImplementation([UITableView class], NSSelectorFromString(@"_applyContentSizeDeltaForEstimatedHeightAdjustments:"), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) { return ^(UITableView *selfObject, CGFloat firstArgv) {
// call super
void (*originSelectorIMP)(id, SEL, CGFloat);
originSelectorIMP = (void (*)(id, SEL, CGFloat))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, firstArgv);
if (fixBugOfTableViewContentSize) {
fixBugOfTableViewContentSize(selfObject);
}
};
});
}
待版本发布后再 close
Bug 表现 列表往上滚动后,尾部出现大量空白,如下方录屏所示:
如何重现
以下是测试 Demo: TestTableViewContentSize.zip
其他信息