avi*_*oss 57 uitableview reloaddata ios contentoffset
CGPoint offset = [_table contentOffset];
[_table reloadData];
[_table setContentOffset:offset animated:NO]; //unuseful
// __block UITableView *tableBlock = _table;
// [self performBlock:^(id sender) {
// [tableBlock setContentOffset:offset];
// } afterDelay:2];
Run Code Online (Sandbox Code Playgroud)
我知道不知道任何被调用的委托方法reloadData
.使用afterDelay:2
哪种黑客可能太短或太长,所以我该如何实现呢?
Mat*_*ala 108
我遇到了麻烦,因为我在cellForRowAtIndexPath方法中混淆了细胞大小.我注意到在执行reloadData之后调整大小的信息已经关闭,所以我意识到我需要在设置内容偏移之前立即强制它进行布局.
CGPoint offset = tableView.contentOffset;
[tableView.messageTable reloadData];
[tableView layoutIfNeeded]; // Force layout so things are updated before resetting the contentOffset.
[tableView setContentOffset:offset];
Run Code Online (Sandbox Code Playgroud)
Sky*_*ker 87
调用reloadData
tableView不会更改内容偏移量.但是,如果您使用的UITableViewAutomaticDimension
是iOS 8中引入的,则可能会出现问题.
当使用UITableViewAutomaticDimension
,需要写委托方法tableView: estimatedHeightForRowAtIndexPath:
并返回UITableViewAutomaticDimension
随着tableView: heightForRowAtIndexPath:
这也返回相同.
对我来说,在使用它时我在iOS 8中遇到了问题.这是因为estimatedHeightForRowAtIndexPath:
即使我正在使用,方法方法也返回了不准确的值UITableViewAutomaticDimension
.这是iOS 8的问题,因为iOS 9设备没有问题.
我通过使用字典存储单元格高度的值并返回它来解决了这个问题.这就是我做的.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *key = @(indexPath.row);
NSNumber *height = @(cell.frame.size.height);
[self.cellHeightsDictionary setObject:height forKey:key];
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *key = @(indexPath.row);
NSNumber *height = [self.cellHeightsDictionary objectForKey:key];
if (height)
{
return height.doubleValue;
}
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
Run Code Online (Sandbox Code Playgroud)
检查高度是否存在是第一次加载页面.
Nik*_*Kov 31
fileprivate var heightDictionary: [Int : CGFloat] = [:]
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
heightDictionary[indexPath.row] = cell.frame.size.height
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
let height = heightDictionary[indexPath.row]
return height ?? UITableViewAutomaticDimension
}
Run Code Online (Sandbox Code Playgroud)
应该调用此方法而不是reloadData
.这适合特定情况.
public func reloadDataAndKeepOffset() {
// stop scrolling
setContentOffset(contentOffset, animated: false)
// calculate the offset and reloadData
let beforeContentSize = contentSize
reloadData()
layoutIfNeeded()
let afterContentSize = contentSize
// reset the contentOffset after data is updated
let newOffset = CGPoint(
x: contentOffset.x + (afterContentSize.width - beforeContentSize.width),
y: contentOffset.y + (afterContentSize.height - beforeContentSize.height))
setContentOffset(newOffset, animated: false)
}
Run Code Online (Sandbox Code Playgroud)
Cyr*_*ril 25
默认情况下,reloadData保留contentOffset.但是,如果您确实具有不准确的estimatedRowHeight值,则可以更新它.
Lou*_*uis 17
我最近在使用reloadData
- reloadData
不更改contentOffset
或滚动表视图.如果偏移量小于新的数据量,它实际上保持不变.
小智 11
如果实施estimatedHeightForRowAtIndexPath
方法而您的估计不正确,则可能会遇到这种情况。
为了解决这个问题,您可以返回一个较大的高度,该高度大于tableView中每个单元格的高度,如下所示:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 800.f; // if 800 is bigger than every possible value of your cell height.
}
Run Code Online (Sandbox Code Playgroud)
如果在dataSource数组的开头插入数据,则需要更改contentOffset
如下:
Swift 3+
func prepareReloadData() {
let previousContentHeight = tableView.contentSize.height
let previousContentOffset = tableView.contentOffset.y
tableView.reloadData()
let currentContentOffset = tableView.contentSize.height - previousContentHeight + previousContentOffset
tableView.contentOffset = CGPoint(x: 0, y: currentContentOffset)
}
Run Code Online (Sandbox Code Playgroud)