簡體   English   中英

嘗試使用NSTableView

[英]Trying to use NSTableView

我是iOS開發人員,正在創建我的第一個Mac應用程序。 嘗試使用NSTableView時遇到一些困難。

extension HomeViewController:NSTableViewDataSource{
    func numberOfRows(in tableView: NSTableView) -> Int {
        print(self.customerApplicationList.count) // '1' gets printed here
        return self.customerApplicationList.count
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?{
        var result:NSTableCellView
        result  = tableView.make(withIdentifier: "firstName", owner: self) as! NSTableCellView
        result.textField?.stringValue = "test"
        return result
    }
}

在此處輸入圖片說明

為什么沒有顯示帶有“ test”值的單元格? (在運行時,未提供此屏幕截圖)

如果將日志放入tableView(_:viewFor:row:)方法中,則會發現它從未被調用過。 為什么會這樣,您可能想知道? 好吧,這很復雜:

眾所周知,AppKit不是使用Swift來實現的; 它是在Objective-C中實現的。 Objective-C是一種非常動態的語言,它允許調用者查詢對象是否響應特定消息,因此,對象要做的就是實現-tableView:viewForTableColumn:row: ,並-tableView:viewForTableColumn:row: Objective -C,AppKit可以找到該方法並調用它。 使用Swift時,事情要復雜一些,因為默認情況下,除非我們通過@objc關鍵字明確地使Swift方法不暴露於Objective-C,否則該方法將覆蓋Objective-C超類方法,或者該方法滿足Objective-C協議。 除了事實證明tableView(_:viewFor:row:)實際上屬於NSTableViewDelegate而不是NSTableViewDataSource之外,這里應該發生第三種情況。 因此,Swift編譯器不會將您的方法視為滿足任何協議,因此它不會暴露給Objective-C。 因此,從AppKit的角度來看,就好像您根本沒有實現它。

要解決您眼前的問題,請將NSTableViewDelegate添加到擴展中,並確保將數據源設置為Interface Builder中的委托。 但是,在制作Mac應用程序時,我發現使用Cocoa綁定更容易填充表格視圖,因為您可以“免費”獲得許多功能,例如按列自動排序,預輸入選擇和選擇管理。 為此,請按照下列步驟操作:

1)確保對象上的array屬性同時標有@objcdynamic關鍵字,並且數組中包含的類是NSObject子類,並且其相關屬性也標有@objcdynamic

class Thingy: NSObject {
    @objc dynamic var name: String

    init(name: String) { self.name = name }
}

class MyViewControllerThingy: NSViewController {
    @objc dynamic var myArray: [Thingy] = [Thingy(name: "Foo"), Thingy(name: "Bar")]
}

這可以確保AppKit可以執行其動態的Objective-C魔術來自動使該屬性符合KVO,因此我們不必自己做(這是必需的,因為Cocoa Bindings是基於KVO構建的)。

2)在Interface Builder中創建一個Array Controller,然后在Bindings Inspector中,將Array Controller的“ Model Key Path”設置為屬性的名稱:

在此處輸入圖片說明

3)現在選擇你的表視圖,並在其綁定檢查,結合它的內容,選擇索引和排序描述符來arrangedObjectsselectionIndexessortDescriptors分別離開“模式鍵路徑”空白每個:

在此處輸入圖片說明

4)在表視圖的單元格中選擇文本字段,轉到其Bindings Inspector,然后將其與objectValue.的模型鍵路徑綁定到表單元格視圖objectValue. 然后要在單元格中查看的屬性名稱:

在此處輸入圖片說明

5)最后,選擇表列並將其Sort Key設置為Attributes Inspector中的屬性名稱(“ Selector”字段可讓您自定義要對對象進行排序的方法;我喜歡對字符串使用localizedStandardCompare:以獲得不區分大小寫的排序,但是對於大多數其他類型,您可以將其保留為默認設置):

在此處輸入圖片說明

等等:

在此處輸入圖片說明

在Interface Builder中,這似乎有些混亂,但是到最后,我們幾乎沒有代碼地設置了整個表。 而且,我們為您的用戶提供了一個非常漂亮的用戶界面,以及一些免費的功能,我最喜歡的功能是通過單擊標題進行自動排序:

在此處輸入圖片說明

這樣做的好處不僅在於您不必費心自己對數組進行重新排序,而且它甚至不會弄亂原始數組的順序。 所做的更改僅用於顯示目的。 這里的數組仍然是["Foo", "Bar"]

NSArrayController另一個非常酷的功能是它將為您管理選擇。 例如,如果表視圖是側邊欄,則可以將右側的另一個視圖綁定到陣列控制器中所選對象,這樣您就可以輕松實現Mail.app的窗格查看器之類的功能,包括指定要使用的占位符之類的內容。如果用戶一次選擇多個對象。 真的很滑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM