2014-08-31 134 views
9

我有一个_TableView与项目,我想设置自动刷新,我不希望它滚动刷新,可以说用户滚动2页下来,刷新触发 - >所以我要把刷新的内容表中的顶部但不中断用户的滚动UITableView刷新不滚动

假定用户是在列18 现在_dataSource被刷新,因此进账可以说4个项目,所以我想用户留在项目他是。

什么是最好的方法来实现它?

+0

希望这些问题的答案将帮助您:http://stackoverflow.com/questions/5872759/uitableview-insert-rows-without-scrolling/11585557#11585557 – stosha 2014-08-31 06:53:05

回答

9

我显示是否只添加一行。您可以将其扩展到多行。

// dataArray is your data Source object 
    [dataArray insertObject:name atIndex:0]; 
    CGPoint contentOffset = self.tableView.contentOffset; 
    contentOffset.y += [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
    [self.tableView reloadData]; 
    [self.tableView setContentOffset:contentOffset]; 

但对于这个工作,你需要定义- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath的方法。否则,你可以直接给你的tableview行高度,如果它是恒定的。

+0

它不是恒定的,谢谢您的回答我将尝试它, – ColdSteel 2014-08-31 06:57:55

+0

是的,那么肯定你已经定义了 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath'的方法。接受我的答案,如果它帮助了你。 – user1190882 2014-08-31 06:59:00

2

我做这样说:

messages.insertContentsOf(incomingMsgs.reverse(), at: 0) 
table.reloadData() 

// This is for the first load, first 20 messages, scroll to bottom 
if (messages.count <= 20) { 
     let indexToScroll = NSIndexPath(forRow: saferSelf.messages.count - 1, inSection: 0) 
     table.scrollToRowAtIndexPath(indexToScroll, atScrollPosition: .Top , animated: false) 
} 
// This is to reload older messages on top of tableview 
else { 
     let indexToScroll = NSIndexPath(forRow: incomingMsgs.count, inSection: 0) 
     table.scrollToRowAtIndexPath(indexToScroll, atScrollPosition: .Top , animated: false) 
     // Remove the refreshControl.height + tableHeader.height from the offset so the content remain where it was before reload 
     let theRightOffset = CGPointMake(0, table.contentOffset.y - refreshControl.frame.height - table.headeView.frame.height) 
     table.setContentOffset(theRightOffset, animated: false) 
} 

...也是,因为我使用动态单元格高度,避免了一些怪事,估计缓存:

var heightAtIndexPath = [NSIndexPath: CGFloat]() 
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return heightAtIndexPath[indexPath] ?? UITableViewAutomaticDimension 
} 
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    heightAtIndexPath[indexPath] = cell.frame.height 
} 
12

这是使用UITableViewAutomatic Dimension时iOS8的错误。我们需要存储表格的内容偏移量,重新加载表格,强制布局并设置contenOffset。

CGPoint contentOffset = self.tableView.contentOffset; 
[self.tableView reloadData]; 
[self.tableView layoutIfNeeded]; 
[self.tableView setContentOffset:contentOffset]; 
+0

关于iOS 8的第一行保存了我的一天。 – CRDave 2017-10-04 08:31:56

16

对于斯威夫特3+

您需要保存当前的UITableView的偏移,然后重新再设置偏移放回UITableView

我创造了这个功能用于此目的:

func reload(tableView: UITableView) { 

    let contentOffset = tableView.contentOffset 
    tableView.reloadData() 
    tableView.layoutIfNeeded() 
    tableView.setContentOffset(contentOffset, animated: false) 

} 

只需使用叫它:reload(tableView: self.tableView)

+0

如果tableview没有改变偏移量会怎样加载新的单元? – 2017-03-29 06:23:40

+0

@RockBalbao - 我不明白你的问题兄弟 – 2017-03-29 06:34:01

+0

我正在使用NSFetchedResultsControllerDelegate。现在我正在使用UIRefreshControl在scrollDown上加载旧单元格。在performFetch数据被加载我只需要重新加载数据。但我不想显示重新加载的单元格。让他们加载上面。当我滚动上面时,只有它们变得可见。所以为了实现这个,我尝试使用这个contentOffset方法。但在reloadData之前和reloadData之后,contentOffset是相同的,虽然它在 – 2017-03-29 06:38:19

0

尝试更换

reloadData

tableView.reloadRowsat: tableView!.indexPathsForVisibleRows!, with: .none),

但您应该关心no cells,如果no cells,此方法应该会导致崩溃。

0

当你要重新加载,你必须

self.tableView.reloadData()

self.tableView。layoutIfNeeded()

,还可以使用这个的UITableViewDelegate

FUNC的tableView(_的tableView:UITableView的,estimatedHeightForRowAt indexPath:IndexPath) - > CGFloat的{ 回报 '你最大小区的高度' }

和您的tableView将保持在以前滚动位置而不滚动

0

此代码将防止不必要的动画并保持滚动视图的内容偏移量,它对我来说工作得很好。

let lastScrollOffset = tableView.contentOffset 
tableView.beginUpdates() 
tableView.reloadData() 
tableView.endUpdates() 
tableView.layer.removeAllAnimations() 
tableView.setContentOffset(lastScrollOffset, animated: false)