2013-11-22 32 views
6

我有一个表格视图,显示通过网络获取的消息。当插入新行时,TableView会滚动到中间

当有新消息进来时,它应该被添加到底部的tableview中。

当新消息进来时,它会正确添加到tableview的底部,但tableview会立即滚动到中间。 (所以,如果我现在已经说了100个单元格,那么单元格50现在将处于滚动视图的中间)。

奇怪的是,这只有在插入之前的滚动点位于tableview的下半部分时才会发生。所以,如果我在查看99单元格10,并添加一行,它会被添加到底部就好了。但是,如果我在查看99的单元格75,并添加一行,则滚动位置又跳到中间(〜单元格50)。

这是我添加新信息的实现代码如下代码:

​​

为什么实现代码如下这样的自动滚动?

+0

你不想滚动你的tableview? –

+0

@hussainShabbir这是滚动没有任何用户交互。当我添加一个新行时,我不希望它自动滚动到现在正在执行的中间。 – Jeff

+0

@Jeff解决这个问题有什么好运?我有同样的问题。使用自我大小的细胞,它疯狂地跳跃。 –

回答

0

我认为你需要改变的行动画无 -

[self.tableView 
insertRowsAtIndexPaths:indexPaths 
withRowAnimation: 
UITableViewRowAnimationNone]; 
+0

我试过所有的动画类型,所有的都有相同的结果:插入后,tableview向上滚动到中心。 – Jeff

0

试试这个

[self.tableView scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

也可以改为middile,顶部或没有位置。

0

我也有这个问题。 NSTableView和UITableView可能类似......它们的默认滚动行为都是SUCK。 TableView并非设计用作电子表格样式编辑器, ,因此多年来我添加了数千行代码,使它像电子表格一样工作 工作。 我希望苹果将只创建NSTableView的一个NSSpreadsheetView子类来解决这一切的东西: - 光标键导航细胞 - 明智的滚动行为 - 添加特殊单元选择

还想看到NSTableView的的NSLogView子类,像Console.app一样具有搜索字段。

我的解决办法是添加几个类别方法:

@implementation NSTableView (VNSTableViewCategory) 

-(NSInteger)visibleRow 
{ 
    NSRect theRect = [self visibleRect]; 
    NSRange theRange = [self rowsInRect:theRect]; 
    if (theRange.length == 0) 
     return -1; 
    else if (NSLocationInRange([self editedRow], theRange)) 
     return [self editedRow];   
    else if (NSLocationInRange([self clickedRow], theRange)) 
     return [self clickedRow];  
    else if (NSLocationInRange([self selectedRow], theRange)) 
     return [self selectedRow]; 
    else 
     return theRange.location + (theRange.length/2); 
} 

-(NSRange)visibleRows 
{ 
    NSRect theRect = [self visibleRect]; 
    NSRange theRange = [self rowsInRect:theRect]; 
    return theRange; 
} 

-(void)scrollRowToVisibleTwoThirds:(NSInteger)row 
{ 
    NSRect theVisRect = [self visibleRect]; 
    NSUInteger numRows = [self numberOfRows]; 
    NSRange visibleRows = [self rowsInRect:theVisRect]; 
    //NSUInteger lastVisibleRow = NSMaxRange(visibleRows); 
    if (NSLocationInRange(row, visibleRows)) 
    { 
     if (row - visibleRows.location < (visibleRows.length * 2/3)) 
     { 
     // may need to scroll up 
     if (visibleRows.location == 0) 
      [self scrollRowToVisible:0]; 
     else if ((row - visibleRows.location) > 2) 
      return; 
     } 
    } 

    NSRect theRowRect = [self rectOfRow:row]; 

    NSPoint thePoint = theRowRect.origin; 
    thePoint.y -= theVisRect.size.height/4; // scroll to 25% from top 

    if (thePoint.y < 0) 
     thePoint.y = 0; 

    NSRect theLastRowRect = [self rectOfRow:numRows-1]; 
    if (thePoint.y + theVisRect.size.height > NSMaxY(theLastRowRect)) 
     [self scrollRowToVisible:numRows-1]; 
    else 
    { 
     [self scrollPoint:thePoint]; // seems to be the 'preferred' method of doing this 

     // kpk note: these other approaches cause redraw artifacts in many situations: 
//  NSClipView *clipView = [[self enclosingScrollView] contentView]; 
//  [clipView scrollToPoint:[clipView constrainScrollPoint:thePoint]]; 
//  [[self enclosingScrollView] reflectScrolledClipView:clipView]; 
//  [self scrollRowToVisible:row]; 

//  [[[self enclosingScrollView] contentView] scrollToPoint:thePoint]; 
//  [[self enclosingScrollView] reflectScrolledClipView:[[self enclosingScrollView] contentView]];  
    } 

} 
@end // NSTableView (VNSTableViewCategory) 

用法示例:

NSRange visRows = [toScenesTable visibleRows]; 
    visRows.length -= 2; 
    if (iAlwaysScroll == YES || !NSLocationInRange(row, visRows)) 
    { 
    [toScenesTable scrollRowToVisibleTwoThirds:row]; // VNSTableViewCategory 
    } 
相关问题