用结构填充 NSTableView

Populate NSTableView with struct

我正在尝试用结构填充 NSTableView。该结构从 Firebase 获取数据。我试图复制我在 iOS 中的做法,但我还没有做到。

var orders = [OrderModel]()

struct OrderModel {
    var order: String!
    var name: String?
    var adress: String?
    var email: String?
}    

从 Firebase 读取:

ref?.child("orders").observe( .childAdded, with: { (snapshot) in
            let dict = snapshot.value as? [String : AnyObject] ?? [:]
            
            let newData = OrderModel(order: dict["order"] as? String, name: dict["name"] as? String, adress: dict["adress"] as? String, email: dict["email"] as? String
            
            self.orders.append(newData)
            })    
    

填充 NSTableView:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
            guard let userCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "ordersCell"), owner: self) as? OrdersTableViewCell else { return nil }
        
        //the object
        let order: OrderModel
        
        //getting the object of selected position
        order = orders[row] //Error index out of range
        
        userCell.orderLabel.stringValue = order.order ?? "Error getting order"
        userCell.nameLabel.stringValue = order.name ?? "Error getting name"
        userCell.adressLabel.stringValue = order.adress ?? "Error getting address"
         return userCell
        }    

我不知道这里唯一的问题是不是这一行:

order = orders[row] //Error index out of range

但这就是我现在的处境。

与 macOS 中的 iOS 不同,有一种更复杂的方法来填充 table 视图:Cocoa 绑定。由于您只对所有数据使用一个单元格视图,因此这是更可取的。

  • 首先让你的结构成为 class 继承自 NSObject

      @objcMembers
      class OrderModel : NSObject {
          dynamic var order: String?
          dynamic var name: String?
          dynamic var adress: String?
          dynamic var email: String?
    
          init(order : String?, name : String?, adress : String?, email : String?) {
              self.order = order
              self.name = name
              self.adress = adress
              self.email = email
          }
      }   
    
  • 删除整个方法tableView: viewFor: row:

  • 在视图控制器中采用NSTableViewDataSourceNSTableViewDelegate

  • 在视图控制器中实现这两个方法

      func numberOfRows(in tableView: NSTableView) -> Int
      {
          return orders.count
      }
    
      func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
          return orders[row]
      }
    
  • Select 项目导航器中的故事板或 xib

  • 删除 table 单元格视图的标识符

  • Select table 视图(不是滚动视图!),按 ⌥⌘7 打开连接检查器并连接(控制拖动)dataSourcedelegate 到视图控制器

  • Select Order table 单元格视图中的文本字段。确保它文本字段。

  • ⌥⌘8打开绑定检查器

  • 单击 Value

    旁边的三角形
  • 勾选Bind To -> Table Cell View

  • 模型关键路径中输入objectValue.order

  • 在其他文本字段中执行相同操作(分别将 order 替换为其他属性)

  • 在从 Firebase 接收数据后的视图控制器中,在主线程的闭包内重新加载 table 视图

    self.orders.append(newData)
    DispatchQueue.main.async { self.tableView.reloadData() }