NSOutlineView是Mac 开发下的具有树状结构的列表视图,主要用它展示具有层级关系的视图。在实际开发中,遇到问题:刷新(reloaddata)后,已展开的项会收起、且滚动到起始位置。我们如何做到刷新但保持刷新前的状态呢?
如何保持展开的状态:
NSOutlineView有以下两个回调:
func outlineView(_ outlineView: NSOutlineView, shouldExpandItem item: Any) -> Bool
func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool
利用这两个回调,我们可以将当前展开项纪录下来,代码示例如下:
//应当展开
func outlineView(_ outlineView: NSOutlineView, shouldExpandItem item: Any) -> Bool {
let itm = item as! Member
for i in 0..<departmentList.count {
let department = departmentList[i]
if department.id == itm.id {
expandSet.insert(i)
}
}
return true
}
//应当收起
func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool {
let itm = item as! Member
for i in 0..<departmentList.count {
let department = departmentList[i]
if department.id == itm.id {
expandSet.remove(i)
break
}
}
return true
}
刷新后展开刷新前展开的项:
self.outlineView.reloadData()
//需要将展开项从大到小排列,即展开是从大到小展开,否则无法全部展开
let expandArr = expandSet.sorted().reversed()
for row in expandArr {
print("需要展开的项:",row)
let item = self.outlineView.item(atRow: row)
self.outlineView.expandItem(item)
}
这样,我们就展开了刷新前已展开的项了
如何保持刷新前的位置:
示例代码如下:
let visibleRect = self.outlineView.visibleRect
self.outlineView.reloadData()
self.outlineView.scrollToVisible(visibleRect)
二者相结合:
let visibleRect = self.outlineView.visibleRect
self.outlineView.reloadData()
let expandArr = expandSet.sorted().reversed()
for row in expandArr {
print("需要展开的项:",row)
let item = self.outlineView.item(atRow: row)
self.outlineView.expandItem(item)
}
self.outlineView.scrollToVisible(visibleRect)
后期将出一篇文章介绍NSOutlineView的使用。