从 NSTableView 中删除排序指示器

RGB*_*rld 4 sorting macos nstableview swift3

如何从NSTableView允许排序的列表中删除排序指示器?我正在 Xcode 8.3.x 中工作,并使用 macOS 的 Swift 3 进行编程。

我有一个NSTableView作为 an 的属性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()
    }
}
Run Code Online (Sandbox Code Playgroud)

在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
    }
}
Run Code Online (Sandbox Code Playgroud)

在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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

RGB*_*rld 5

要从表中删除排序,请将变量设置为等于 的空数组NSSortDescriptors,然后将表设置sortDescriptors为空数组并调用reloadData()

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

@IBAction func reloadUnsortedData(_ sender: Any) {
    tableView.sortDescriptors = defaultSortDescriptors
    tableView.reloadData()
}
Run Code Online (Sandbox Code Playgroud)