Dea*_*ith 60 iphone uitableview uiscrollview uikit
我有一个tableView,我在顶部插入行.
虽然我这样做,但我希望当前视图保持完全静止,因此只有向上滚动时才会显示行.
我已经尝试保存底层UIScrollview的当前位置并在插入行之后重置位置,但这导致抖动,上下,尽管它最终返回到同一位置.
有没有一个很好的方法来实现这一目标?
更新:我使用的是beginUpdate,然后是insertRowsAtIndexPath,endUpdates.没有reloadData调用.
scrollToRowAtIndexPath跳转到当前单元格的顶部(在添加行之前保存).
我试过的另一种方法,最终以正确的速度结束,但有一个颤抖的是.
save tableView currentOffset. (Underlying scrollView method)
Add rows (beginUpdates,insert...,endUpdates)
reloadData ( to force a recalulation of the scrollview size )
Recalculate the correct new offset from the bottom of the scrollview
setContentOffset (Underlying scrollview method)
Run Code Online (Sandbox Code Playgroud)
麻烦是reloadData导致scrollview/tableview开始短暂滚动,然后setContentOffset将它返回到正确的位置.
有没有办法让tableView在没有开始显示的情况下计算出它的新尺寸?
将整个事物包装在beginAnimation commitAnimation中也没有多大帮助.
更新2:这显然可以完成 - 当您下载更新时,请参阅官方Twitter应用程序.
Ami*_*itP 48
实际上没有必要总结所有行的高度,重新加载表后的新contentSize已经表示了这一点.因此,您所要做的就是计算contentSize高度的增量并将其添加到当前偏移量.
...
CGSize beforeContentSize = self.tableView.contentSize;
[self.tableView reloadData];
CGSize afterContentSize = self.tableView.contentSize;
CGPoint afterContentOffset = self.tableView.contentOffset;
CGPoint newContentOffset = CGPointMake(afterContentOffset.x, afterContentOffset.y + afterContentSize.height - beforeContentSize.height);
self.tableView.contentOffset = newContentOffset;
...
Run Code Online (Sandbox Code Playgroud)
小智 24
-(void) updateTableWithNewRowCount : (int) rowCount
{
//Save the tableview content offset
CGPoint tableViewOffset = [self.tableView contentOffset];
//Turn of animations for the update block
//to get the effect of adding rows on top of TableView
[UIView setAnimationsEnabled:NO];
[self.tableView beginUpdates];
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:SECTION_TO_INSERT];
[rowsInsertIndexPath addObject:tempIndexPath];
heightForNewRows = heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
[self.tableView insertRowsAtIndexPaths:rowsInsertIndexPath withRowAnimation:UITableViewRowAnimationNone];
tableViewOffset.y += heightForNewRows;
[self.tableView endUpdates];
[UIView setAnimationsEnabled:YES];
[self.tableView setContentOffset:tableViewOffset animated:NO];
}
-(int) heightForCellAtIndexPath: (NSIndexPath *) indexPath
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
int cellHeight = cell.frame.size.height;
return cellHeight;
}
Run Code Online (Sandbox Code Playgroud)
只需传入新行的行数即可插入顶部.
an0*_*an0 21
@ Dean使用图像缓存的方式实在太过分了,我认为它破坏了UI的响应能力.
一种正确的方法:使用UITableView子类并覆盖-setContentSize:在某种程度上,您可以通过某种方式计算向下推送表视图的数量,并通过设置contentOffset来抵消该视图.
这是一个最简单的示例代码,用于处理所有插入发生在表视图顶部的最简单情况:
@implementation MyTableView
- (void)setContentSize:(CGSize)contentSize {
// I don't want move the table view during its initial loading of content.
if (!CGSizeEqualToSize(self.contentSize, CGSizeZero)) {
if (contentSize.height > self.contentSize.height) {
CGPoint offset = self.contentOffset;
offset.y += (contentSize.height - self.contentSize.height);
self.contentOffset = offset;
}
}
[super setContentSize:contentSize];
}
@end
Run Code Online (Sandbox Code Playgroud)
And*_*rev 17
有同样的问题,并找到了解决方案.
save tableView currentOffset. (Underlying scrollView method)
//Add rows (beginUpdates,insert...,endUpdates) // don't do this!
reloadData ( to force a recalulation of the scrollview size )
add newly inserted row heights to contentOffset.y here, using tableView:heightForRowAtIndexPath:
setContentOffset (Underlying scrollview method)
Run Code Online (Sandbox Code Playgroud)
像这样:
- (CGFloat) firstRowHeight
{
return [self tableView:[self tableView] heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
}
...
CGPoint offset = [[self tableView] contentOffset];
[self tableView] reloadData];
offset.y += [self firstRowHeight];
if (offset.y > [[self tableView] contentSize].height) {
offset.y = 0;
}
[[self tableView] setContentOffset:offset];
...
Run Code Online (Sandbox Code Playgroud)
工作完美,没有毛刺.
我做了一些核心数据样本项目的测试,让它静止不动,同时在顶部可见细胞上方添加新细胞.此代码需要调整屏幕上空白空间的表,但一旦屏幕填满,它就可以正常工作.
static CGPoint delayOffset = {0.0};
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
if ( animateChanges )
[self.tableView beginUpdates];
delayOffset = self.tableView.contentOffset; // get the current scroll setting
}
Run Code Online (Sandbox Code Playgroud)
在单元格插入点添加了此项.您可以对细胞删除进行对应减法.
case NSFetchedResultsChangeInsert:
delayOffset.y += self.tableView.rowHeight; // add for each new row
if ( animateChanges )
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
Run Code Online (Sandbox Code Playgroud)
最后
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
if ( animateChanges )
{
[self.tableView setContentOffset:delayOffset animated:YES];
[self.tableView endUpdates];
}
else
{
[self.tableView reloadData];
[self.tableView setContentOffset:delayOffset animated:NO];
}
}
Run Code Online (Sandbox Code Playgroud)
使用animateChanges = NO时,在添加单元格时,我看不到任何移动.
在使用animateChanges = YES进行测试时,"颤抖"就在那里.似乎单元格插入的动画与动画表格滚动的速度不同.虽然最后的结果可能会以可见单元格的确切位置结束,但整个表格似乎移动了2或3个像素,然后向后移动.
如果动画速度可以相等,它可能看起来保持不变.
但是,当我按下按钮在上一个动画完成之前添加行时,它会突然停止动画并开始下一个动画,突然改变位置.
小智 5
@院长,
您可以像这样更改代码以防止动画.
[tableView beginUpdates];
[UIView setAnimationsEnabled:NO];
// ...
[tableView endUpdates];
[tableView setContentOffset:newOffset animated:NO];
[UIView setAnimationsEnabled:YES];
Run Code Online (Sandbox Code Playgroud)
Jos*_*ura -1
使用scrollToRowAtIndexPath:atScrollPosition:animated:怎么样?您应该能够仅向数据源添加一个元素,使用上述方法设置行并重新加载表...
| 归档时间: |
|
| 查看次数: |
28005 次 |
| 最近记录: |