2017-01-31 94 views
1

我有一個基於視圖的NSTableView顯示消息/信息的時間線。行高是可變的。新消息經常使用insertRows在桌子的頂部增加插入行時保持相同的NSTableView滾動位置

NSAnimationContext.runAnimationGroup({ (context) in 
    context.allowsImplicitAnimation = true 
    self.myTable.insertRows(at: indexSet, withAnimation: [.effectGap]) 
}) 

雖然用戶停留在表的頂部,消息不斷被插入在頂部,向下推動現有的:在這種情況下通常的行爲。

一切正常,除了如果用戶向下滾動,新插入的消息不應該使表滾動

我希望tableView保持它在用戶滾動時的位置或用戶已向下滾動。

換句話說,如果頂部行100%可見,tableView只能被新插入的行按下。

我試圖把桌上的不是很快恢復其位置,這樣移動的錯覺:

// we're not at the top anymore, user has scrolled down, let's remember where 
let scrollOrigin = self.myTable.enclosingScrollView!.contentView.bounds.origin 
// stuff happens, new messages have been inserted, let's scroll back where we were 
self.myTable.enclosingScrollView!.contentView.scroll(to: scrollOrigin) 

但它不表現爲我想。我嘗試了很多組合,但我認爲我並不理解剪輯視圖,滾動視圖和表視圖之間的關係。

或者,也許我在XY問題區域,並有不同的方式來獲得這種行爲?

回答

4

忘掉滾動視圖,剪輯視圖,contentView,documentView並關注表視圖。表視圖可見部分的底部不應移動。您可能錯過了翻轉的座標系。

NSPoint scrollOrigin; 
NSRect rowRect = [self.tableView rectOfRow:0]; 
BOOL adjustScroll = !NSEqualRects(rowRect, NSZeroRect) && !NSContainsRect(self.tableView.visibleRect, rowRect); 
if (adjustScroll) { 
    // get scroll position from the bottom: get bottom left of the visible part of the table view 
    scrollOrigin = self.tableView.visibleRect.origin; 
    if (self.tableView.isFlipped) { 
     // scrollOrigin is top left, calculate unflipped coordinates 
     scrollOrigin.y = self.tableView.bounds.size.height - scrollOrigin.y; 
    } 
} 

// insert row 
id object = [self.arrayController newObject]; 
[object setValue:@"John" forKey:@"name"]; 
[self.arrayController insertObject:object atArrangedObjectIndex:0]; 

if (adjustScroll) { 
    // restore scroll position from the bottom 
    if (self.tableView.isFlipped) { 
     // calculate new flipped coordinates, height includes the new row 
     scrollOrigin.y = self.tableView.bounds.size.height - scrollOrigin.y; 
    } 
    [self.tableView scrollPoint:scrollOrigin]; 
} 

我沒有測試「tableView留在它在用戶滾動的位置」。

+0

這正是我所需要的。非常感謝! – Moritz