1

I am building a Cocoa Swift app which have NSCollectionViews and have an NSCollectionView which has custom NSCollectionViewItem which has like below as in photo.

enter image description here

My purpose is building something like a calendar and as you understand from the image, I want to change date value and date string. Even tried it like below couldn't achieve it and did not understand what effects it.

Here is my custom NSCollectionViewItem

class CalendarDateCell: NSCollectionViewItem {

    
    @IBOutlet weak var dateNameString: NSTextField!
    @IBOutlet weak var dateNumberString: NSTextField!
    
    
    override func loadView() {
        super.loadView()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }
    
}

Here is my itemForRepresentedObjectAt function.

func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        // 4
        let item = calendarCollectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "CalendarDateCell"), for: indexPath)
        guard let collectionViewItem = item as? CalendarDateCell else {return item}
        
        
        
        switch indexPath.item % 3 {
        case 0,1:
            collectionViewItem.dateNameString.stringValue = "0-1"
        case 2:
            collectionViewItem.dateNameString.stringValue = "3"
        default:
            break
        }
        
        return collectionViewItem
    }

I tried it for testing, UI is done work but I did not change the property of the NSCollectionViewItem as a change of NSIndexPath

Then I added a String variable to NSCollectionViewItem and observe it with didSet method and I can change the variable but it's not effective for UI elements of AppKit.

How can I fix the problem? Any suggestions?

Edit:

I add a model for NSCollectionViewItem

var calendarModel: CalendarModel = CalendarModel() {
        didSet {
            dateNameString.stringValue = calendarModel.name
        }
    }

Then change it in controller as

collectionViewItem.calendarModel.name = "1231"

but never affects.

Thanks in advance

eemrah
  • 1,603
  • 3
  • 19
  • 37
  • On-Topic: you should represent the data of the cells as a separate list of models. And then the function you have written there should only read the model from the list of models. Off-Topic: Curious: is this a fairly "new" macOS app? If it is, why not use `SwiftUI` instead of AppKit? :) – Sajjon Jul 02 '20 at 14:10
  • OnTopic: thank you so much Sajjon, can you provide a simple example for the question? OffTopic: yeah it's new macOS app because the company not ready for built it with SwiftUI yet so they wanted to build it with `Cocoa` never mentioned `SwiftUI` but I wish I start to build it with `SwiftUI` – eemrah Jul 02 '20 at 14:14
  • 1
    There is literally thousands of tutorials on this. I would implement a method in `CalendarDateCell` which takes the model and populates the data with its properties. Achives nice encapsulation. – Sajjon Jul 02 '20 at 14:26
  • Thank you but I want to be sure if you mean what I understand as I edited for encapsulation. Can you verify it if it's true or not? – eemrah Jul 02 '20 at 14:30
  • Are you calling `reloadData()` after model changes? https://developer.apple.com/documentation/appkit/nscollectionview/1528264-reloaddata – Sajjon Jul 02 '20 at 14:31
  • yeah, but never changed. I looked at `https://dev.to/onmyway133/making-nscollectionview-programatically-in-swift-2i85` and `https://www.raywenderlich.com/783-nscollectionview-tutorial` but all of them are same as mine. – eemrah Jul 02 '20 at 14:36

0 Answers0