macoscocoaswift4nstableviewnsimageview

Display Image View in Table View conditionally in Swift


I'm trying to display an image in a table view cell view on the condition of a Boolean value.

The Boolean is a representation of the state of an object of the class "Book" where the objects are initialized:

class Book: NSObject, Codable {
    @objc dynamic var author: String
    @objc dynamic var title: String
    @objc dynamic var lentBy: String
    @objc dynamic var available: Bool {
        if lentBy == "" {
            return true
        } else {return false}
    }

    init(author: String, title: String, lentBy: String) {
        self.author = author
        self.title = title
        self.lentBy = lentBy

    }
}

If the String lentBy is not specified, the Bool available returns true: no one has lent the book and hence it should be available. Binding the available object to the table view, the respective table view cell displays either 1 or 0. Instead of 1 or 0 I would like it to display an image: NSStatusAvailable or NSStatusUnavailable.

Have a look at this: https://i.sstatic.net/fbsjO.png. Where the text field "Geliehen von" (lent by) is empty, the status is 1 and should display the green circle; otherwise a red circle. The green circle you see now is simply dragged into the table cell view and is non-functional. But this is the idea.

Now I'm wondering how to display the respective image view instead of the Bool 1 or 0.

The table view is constructed with the interface builder in a storyboard. If I'm trying to make changes to it programmatically, nothing gets display in the table view anymore. I suppose this is due to the set bindings. Removing the bindings just for the last column doesn't work. This is how I tried it (without implementation of the image view; I don't know how to do that programmatically):

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        if tableColumn == tableView.tableColumns[2] {
            let cellIdentifier = "statusCellID"
            let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: self) as? NSTextField

            if let cell = cell {
                cell.identifier = NSUserInterfaceItemIdentifier(rawValue: cellIdentifier)
                cell.stringValue = books[row].lentBy
            }
            return cell
        }
        return nil
    }

What's the best solution to achieve this? Could I somehow, instead of a Bool, directly return the respective, e.g. CGImage types for lentBys representation available?


Solution

  • You are using Cocoa Bindings. This makes it very easy.