我還沒有測試或嘗試以下,但認爲我會給它一個鏡頭無論如何。首先,用NS *控制器管理任何與NSTableView或NSOutlineView複雜的事情是痛苦的,並犧牲精確控制以換取簡單。如果您發現自己在這種情況下發生了對抗行爲,請考慮在您自己的自定義控制器中實施數據源和委託協議(NSTableViewDataSource,NSTableViewDelegate或NSOutlineViewDataSource,NSOutlineViewDelegate)。第二,Warren Burton關於發射KVO通知的評論是有意義的,因爲你應該告訴負責控制器(你的NSTreeController)有關這些改變,因爲它是控制(和觀察)該集合的人。更重要的是,你應該直接使用NSTreeController的add/insert/remove方法。你現在這樣做的方式(每當你取消時重新打開整個結構然後重新設置)將導致整個樹重新加載。由於控制器正在觀察該集合,因此它會告訴大綱視圖自行刷新,可能會首先看到一個空的輪廓,然後是大綱的進一步擴展版本,這將會失去用戶的擴展狀態等。修改模型通過樹控制器將允許更智能,更高效的視圖更新。
第三,可以考慮通過繼承NSTreeController並重寫添加/插入取我的第二個點的優勢之上/刪除方法來做到以下幾點:
- 詢問外形上看其
-visibleRect
。
- 致電超級啓動更改。
- 告訴大綱視圖到
-scrollRectToVisible:
。
您可能不得不通過在主線程上調度它來延遲第3步的調用(所以它在當前通過運行循環之後發生)。或者,或者替換第3步,將可見矩形存儲在某個地方,然後執行NSOutlineViewDelegate方法檢查此標誌,如果rect非零,則調用-scrollRectToVisible:
(請記住將其重置爲NSZeroRect,以便它不嘗試每次添加或刪除大綱行時調整滾動)。
笨重的,但一個合理的(?)路徑,讓您保持NSTreeController。第四,或者(和我想去的方式),你可以完全刪除NSTreeController並在你自己的控制器類中實現NSOutlineViewDataSource(和NSOutlineViewDelegate)協議,並讓該控制器直接處理添加到樹結構或從樹結構中刪除。然後它變得更清潔,因爲您不必擔心KVO的時間。在添加任何節點時,您可以注意到可見矩形,更新大綱視圖,然後在同一個方法中調整全部滾動,並在運行循環中跳轉。
我希望這可以幫助,而不是太漫無邊際。 :-)
您是重新加載整個大綱視圖還是僅需要更新的特定項目? – rocky
@rocky我沒有明確重新加載大綱視圖。樹控制器爲我重新加載它。 – tbodt
什麼對象得到這個消息?相關的FS節點表示還是控制器?對於我爲什麼要在這裏發射KVO有點不清楚。另外你怎麼刷新孩子。你能證明這一點嗎?我構建了一個快速樹控制器/ nsoutlineview,只要我不開啓KVO,我不會在更新時重置視圖。 –