【问题标题】:Populate NSTableView with struct使用结构填充 NSTableView
【发布时间】:2021-03-01 16:29:18
【问题描述】:

我正在尝试使用结构填充 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] //错误索引超出范围

但这就是我现在所处的位置。

【问题讨论】:

  • 请添加您的NSTableViewDataSource 代码。当self.orders 发生变化时如何更新表格视图?

标签: swift macos cocoa nstableview


【解决方案1】:

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

  • 首先让你的结构成为一个继承自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]
      }
    
  • 在项目导航器中选择storyboard或xib

  • 移除表格单元格视图的标识符

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

  • 在表格单元格视图中选择 Order 文本字段。确保它文本字段。

  • ⌥⌘8 打开绑定检查器

  • 点击Value旁边的三角提示

  • 检查Bind To -> Table Cell View

  • 模型密钥路径中输入objectValue.order

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

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

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

【讨论】:

  • 我刚刚删除了我的评论。我发现了导致崩溃的错误。我已将 NSTableView 连接到 ViewController。现在没有崩溃。但是,对于新类 OrderModel,它无法从 Firebase 正确下载。这仍然是从 Firebase 获取数据的正确方法吗:let newData = OrderModel(order: dict["order"] as? String, ...(and so on)
  • 我不熟悉 Firebase,抱歉。创建一些虚拟对象以至少证明表格视图是否有效。
  • viewDidLoad 我做了:let data = OrderModel(order: "Test order", name: "Peter Parker", adress: "Kings Road", email: "peter@parker.com) 和 orders.append(data)` 但这也行不通。我是不是完全失去了思路??
  • 如答案中所述,您必须在附加对象后重新加载表格视图。
  • 是的,但是当我从上面的评论中` print("Data: (data)")` 时(在viewDidLoad 中),它会打印:Data: <MyProject.OrderModel: 0x600002916b50> 所以看来 OrderModel 不是人口稠密?
猜你喜欢
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 2011-08-13
相关资源
最近更新 更多