0

I'm trying to update a NSTextField title inside of a NSCollectionViewItem from a parent NSCollectionViewDataSource. Here is my code.

NSCollectionViewDataSource

    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        let cell = collectionView.makeItem(
          withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "MacDeviceItem"),
          for: indexPath
        ) as! MacDeviceItem

        let device = devicesList[indexPath.item]
        cell.deviceName = "Hello World"
        return cell
    }

NSCollectionViewItem

class MacDeviceItem: NSCollectionViewItem {
    dynamic public var deviceName:String = "Unknown Device Name"

    @IBOutlet weak var deviceImage: NSImageView!
    @IBOutlet weak var deviceNameLabel: NSTextField!
    @IBOutlet weak var deviceStatusLabel: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.wantsLayer = true
        updateSelection()
    }

    override func viewDidLayout() {
        super.viewDidLayout()
        view.layer?.cornerRadius = 7
        print(deviceName)
    }

    override func viewDidAppear() {
        self.deviceNameLabel?.stringValue = deviceName
    }

    private var selectionColor : CGColor {
        let selectionColor : NSColor = (isSelected ? .controlAccentColor : .clear)
        return selectionColor.cgColor
    }

    private var selectionTextColor : NSColor {
        let selectionTextColor : NSColor = (isSelected ? .selectedMenuItemTextColor : .controlTextColor)
        return selectionTextColor
    }

    override var isSelected: Bool {
        didSet {
            super.isSelected = isSelected
            updateSelection()
            // Do other stuff if needed
        }
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        updateSelection()
    }

    private func updateSelection() {
        view.layer?.backgroundColor = self.selectionColor
        deviceNameLabel?.textColor = self.selectionTextColor
        deviceStatusLabel?.textColor = self.selectionTextColor
    }

}

If I print the value of deviceName on viewDidLoad the value is there. However when trying to set the label in ViewDidAppear or nothing happens and the variable has been reset back to the default value. I'm pretty new to Swift but have had some previous experience in Objective-C but don't remember having this issue.

Kieran Crown
  • 307
  • 5
  • 16

1 Answers1

0

Here you don't actually need the variable deviceName: String. You could directly set the value to the deviceNameLabel: NSTextField, like this:

cell.deviceNameLabel.stringValue = "Hello World"

If you actually need the variable you could try the didSet approach, like this:

public var deviceName:String = "Unknown Device Name" {
    didSet {
        cell.deviceNameLabel.stringValue = deviceName
    }
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
  • So when trying to directly update the value using this code `cell.deviceNameLabel?.stringValue = "Hello World"` Nothing happens. The NSTextField doesn't actually change value – Kieran Crown Jun 04 '20 at 09:00
  • If you using this method remove the `deviceName:String` and you're good to go. – Frankenstein Jun 04 '20 at 09:01
  • I have done this but still nothing happens. I'm more than happy to share my code for you to replicate the issue. – Kieran Crown Jun 04 '20 at 09:02
  • Did you try the `didSet` method? Did that method work? Also, try to print out each time the `deviceName` is set when trying it out. – Frankenstein Jun 04 '20 at 09:10
  • Printing the device name inside of the didSet does print out the value but I get a `Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value` with your stringValue code I have to change it to read `self.deviceNameLabel?.stringValue = deviceName` but then the label still doesn't update – Kieran Crown Jun 04 '20 at 09:18
  • The error you're getting simply means the `IBOutlet weak var deviceNameLabel: NSTextField!` connection should be fixed. Untill you fix this you can't set a text to NSTextField programmatically. – Frankenstein Jun 04 '20 at 09:22
  • How can I do this? I can update the text via a push button click just not when creating the item – Kieran Crown Jun 04 '20 at 09:25