2017-07-27 51 views
1

如何从允许排序的NSTableView中删除排序指示器?我正在使用Xcode 8.3.x和使用Swift 3编写macOS。从NSTableView中删除排序指示器

我有一个NSTableView作为NSViewController的财产。当用户点击标题单元格时,我已经实施了排序。这一切都按预期工作。

当表格第一次加载时,它是未排序的,并且没有排序指示器可见(这是期望的行为)。标题单元格被点击后,数据将被正确排序,并将排序指示器添加到标题单元格中。到目前为止,所有的都很好

现在我有一个按钮来重新加载未排序的表。单击该按钮确实可以重新加载数据(未排序),但排序指示符仍然存在(但具有误导性)。当按下“加载未排序”按钮时,我想删除排序指示器,因为指示器现在是错误的(列表未排序),但在按下“加载未排序”按钮之前,指示器仍然可见。

我试过tableView.setIndicatorImage(newImage, in: column)试图设置指标为零或1像素的图像,但它什么都不做。

我也试过drawSortIndicator没有成功。

为了让表格最初加载未排序的数据,我添加了一个不存在的列的排序和初始加载,我排序在该列上。这允许我总是显示一个排序列表 - 未排序的实际排序列“无”。

因此,最终,我希望没有排序加载表。我想允许排序,并且我希望能够以未排序的方式重新加载,从而删除可能存在的任何排序指示符。

class AppInfoViewController: NSViewController { 

    @IBOutlet weak var tableView: NSTableView! 

    var dataDict: [AppInfo] = AppInfoManager.sharedInstance.appInfoArray 
    var sortOrder = AppInfoManager.ColumnOrder.None 
    var sortAscending = true 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 
     tableView.delegate = self 
     tableView.dataSource = self 
     tableView.target = nil 

     let descriptor_0 = NSSortDescriptor(key: AppInfoManager.ColumnOrder.Name.rawValue, ascending: true) 
     let descriptor_1 = NSSortDescriptor(key: AppInfoManager.ColumnOrder.Date.rawValue, ascending: true) 
     let descriptor_2 = NSSortDescriptor(key: AppInfoManager.ColumnOrder.Size.rawValue, ascending: true) 

     tableView.tableColumns[0].sortDescriptorPrototype = descriptor_0 
     tableView.tableColumns[1].sortDescriptorPrototype = descriptor_1 
     tableView.tableColumns[2].sortDescriptorPrototype = descriptor_2 
    } 

    override func viewWillAppear() { 
     super.viewWillAppear() 
     loadSortedData() 
    } 

    @IBAction func reloadUnsortedData(_ sender: Any) { 
     dataDict = AppInfoManager.sharedInstance.appInfoArray 
     sortOrder = AppInfoManager.ColumnOrder.None 
     sortAscending = false 
     let column = tableView.tableColumns[0] 

     //tableView.setIndicatorImage(nil, in: column) 
     //tableView.headerView?.needsDisplay = true 
     //tableView.headerView?.display() 

     column.headerCell.drawSortIndicator(withFrame: column.headerCell.sortIndicatorRect(forBounds: (tableView.headerView?.frame)!), in: column.tableView!, ascending: false, priority: 1) 
     tableView.reloadData() 
    } 

    func loadSortedData() { 
     dataDict = AppInfoManager.sharedInstance.contentsOrderedBy(sortOrder, ascending: sortAscending) 
     tableView.reloadData() 
    } 
} 

在AppInfoManager类,排序来完成类似如下:

class AppInfoManager { 

    static let sharedInstance: AppInfoManager = AppInfoManager() 
    var appInfoArray:[AppInfo] = [AppInfo]() 

    public enum ColumnOrder: String { 
     case None 
     case Name 
     case Date 
     case Size 
    } 

    func contentsOrderedBy(_ orderedBy: ColumnOrder, ascending: Bool) -> [AppInfo] { 
     let sortedFiles: [AppInfo] 
     switch orderedBy { 
      case .Name: 
       if ascending == true { 
        sortedFiles = appInfoArray.sorted(by: {$0.appTitle < $1.appTitle }) 
       } else { 
        sortedFiles = appInfoArray.sorted(by: {$0.appTitle > $1.appTitle }) 
       } 
      case .Date: 
       if ascending == true { 
        sortedFiles = appInfoArray.sorted(by: {$0.pid < $1.pid }) 
       } else { 
        sortedFiles = appInfoArray.sorted(by: {$0.pid > $1.pid }) 
       } 
      case .Size: 
       if ascending == true { 
        sortedFiles = appInfoArray.sorted(by: {$0.executableName < $1.executableName }) 
       } else { 
        sortedFiles = appInfoArray.sorted(by: {$0.executableName > $1.executableName }) 
       } 
      case .None: 
       sortedFiles = appInfoArray 
     } 
     return sortedFiles 
    } 
} 

在AppInfoViewController(NSTableViewDataSource)

extension AppInfoViewController: NSTableViewDataSource { 

    func numberOfRows(in tableView: NSTableView) -> Int { 
     return dataDict.count 
    } 

    func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) { 
     guard let sortDescriptor = tableView.sortDescriptors.first else { 
      return 
     } 

     if let order = AppInfoManager.ColumnOrder(rawValue: sortDescriptor.key!) { 
      sortOrder = order 
      sortAscending = sortDescriptor.ascending 
      loadSortedData() 
     } 
    } 
} 
+0

你实现了'tableView(_:sortDescriptorsDidChange:)'吗?什么时候调用loadSortedData? – Willeke

+0

是的,'tableView(_:sortDescriptorsDidChange:)'一直是实现的。我添加了代码来提问。从'viewWillAppear'和'sortDescriptorsDidChange'调用。 – rgbworld

回答

0

为了除去从表排序,设置一个变量等于一空数组NSSortDescriptors,然后将该表的sortDescriptors设置为空数组并调用reloadData()

class AppInfoViewController: NSViewController { 
    let defaultSortDescriptors = [NSSortDescriptor]() 
} 

@IBAction func reloadUnsortedData(_ sender: Any) { 
    tableView.sortDescriptors = defaultSortDescriptors 
    tableView.reloadData() 
}