Search code examples
macoscocoaswiftcocoa-bindingsnscollectionview

Is there a way to set up a NSCollectionView programmatically in Swift?


I'm coming from the iOS development and I am wondering if there is a way to set up a NSCollectionView programmatically like a UICollectionView in iOS? And add the NSCollectionViewItems in code. Or is the only way to set up a NSCollectionView to use bindings?

Thank You!


Solution

  • Thanks to @stevesliva for pointing me to this SO answer. I converted it to Swift. This is what I got.

    I am creating a NSCollectionView in the ViewController:

    import Cocoa
    
    class ViewController: NSViewController {
    
        var titles = [String]()
        var collectionView: NSCollectionView?
    
        override func viewDidLoad() {
            super.viewDidLoad()
        
            self.titles = ["Banana", "Apple", "Strawberry", "Cherry", "Pear", "Pineapple", "Grape", "Melon"]
            collectionView = NSCollectionView(frame: self.view.frame)
            collectionView!.itemPrototype = CollectionViewItem()
            collectionView!.content = self.titles
            collectionView!.autoresizingMask = NSAutoresizingMaskOptions.ViewWidthSizable | NSAutoresizingMaskOptions.ViewMaxXMargin | NSAutoresizingMaskOptions.ViewMinYMargin | NSAutoresizingMaskOptions.ViewHeightSizable | NSAutoresizingMaskOptions.ViewMaxYMargin
        
            var index = 0
            for title in titles {
                var item = self.collectionView!.itemAtIndex(index) as! CollectionViewItem
                item.getView().button?.title = self.titles[index]
                index++
            }
            self.view.addSubview(collectionView!) 
        }
    }
    

    The created CollectionViewItem in the ViewController just load a view, where I set up the item view itself.

    import Cocoa
    
    class CollectionViewItem: NSCollectionViewItem {
    
        var itemView: ItemView?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do view setup here.
        }
    
        override func loadView() {
            self.itemView = ItemView(frame: NSZeroRect)
            self.view = self.itemView!
        }
    
        func getView() -> ItemView {
            return self.itemView!
        }
    }
    

    The view itself:

    import Cocoa
    
    class ItemView: NSView {
    
        let buttonSize: NSSize = NSSize(width: 100, height: 20)
        let itemSize: NSSize = NSSize(width: 120, height: 40)
        let buttonOrigin: NSPoint = NSPoint(x: 10, y: 10)
    
        var button: NSButton?
    
        override func drawRect(dirtyRect: NSRect) {
            super.drawRect(dirtyRect)
    
            // Drawing code here.
        }
    
        override init(frame frameRect: NSRect) {
            super.init(frame: NSRect(origin: frameRect.origin, size: itemSize))
            let newButton = NSButton(frame: NSRect(origin: buttonOrigin, size: buttonSize))
            newButton.bezelStyle = NSBezelStyle.RoundedBezelStyle
            self.addSubview(newButton)
            self.button = newButton;
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func setButtonTitle(title: String) {
            self.button!.title = title
        }
    }
    

    To set the button title, I am using kind of a hack. (the for-loop in the ViewController) If there is a better way to set the title please feel free to leave a comment.