2017-07-27 13 views
1

並べ替えを許可するNSTableViewからソートインジケータを削除するにはどうすればよいですか?私はXcode 8.3.xで作業しており、MacOSのSwift 3でプログラミングしています。NSTableViewからソートインジケータを削除します

NSViewControllerのプロパティとしてNSTableViewがあります。ユーザーがTitleセルをクリックするとソートが実装されました。これはすべて期待通りに機能します。

テーブルが最初にロードされるとき、テーブルはソートされておらず、ソートインジケータは表示されません(これは望ましい動作です)。タイトルセルがクリックされると、データが適切にソートされ、ソートインジケータがヘッダセルに追加されます。もう一度これまでのすべての良い。

ここでは、の並べ替えを解除するボタンがあります。テーブル。ボタンをクリックすると、データは正常に再ロードされます(ソートされません)。ソートインジケータはまだ表示されますが、誤解を招く可能性があります。インジケータが間違っている(リストはソートされていない)ため、まだソートされていないボタンを押すと、ソートインジケータが削除されます。 。

私はtableView.setIndicatorImage(newImage, in: column)をインジケータをnilまたは1ピクセルイメージに設定しようと試みましたが、何もしません。

私もdrawSortIndicatorを試してみました。

最初にテーブルをソートされていないデータで読み込むために、存在しないカラムのソートを追加しました。初期ロード時には、そのカラムをソートします。これにより、並べ替えられたリストを常に表示することができます。ソートされていないリストは実際には列「None」にソートされています。

最終的には、ソートせずにテーブルをロードします。私は並べ替えを許可したいので、並べ替えられていないとしてリロードすることができます。 AppInfoManagerクラスの

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() 
    } 
} 

、ソートは以下のように達成される:に等しい変数を設定し、テーブルからソートを削除するAppInfoViewControllerで

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 
    } 
} 

を(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() 
} 
関連する問題