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

后端 未结 3 2117
猫巷女王i
猫巷女王i 2020-12-15 12:09

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

相关标签:
3条回答
  • 2020-12-15 12:25

    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.

    0 讨论(0)
  • 2020-12-15 12:30

    You need to embed NSCollectionView within NSScrollView. Code below is in Swift 4

    Setup NSCollectionView

    let layout = NSCollectionViewFlowLayout()
    layout.minimumLineSpacing = 4
    
    collectionView = NSCollectionView()
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.collectionViewLayout = layout
    collectionView.allowsMultipleSelection = false
    collectionView.backgroundColors = [.clear]
    collectionView.isSelectable = true
    collectionView.register(
      Cell.self,
      forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell")
    )
    

    Setup NSScrollView

    scrollView = NSScrollView()
    scrollView.documentView = collectionView
    view.addSubview(scrollView)
    

    Here's a simple NSCollectionViewItem

    class Cell: NSCollectionViewItem {
      let label = NSTextField()
      let imageView = NSImageView()
    
      override func loadView() {
        self.view = NSView()
        self.view.wantsLayer = true
      }
    }
    
    0 讨论(0)
  • 2020-12-15 12:47

    For Swift 2.0, you will need to change the collectionView!.autoresizingMask line to:

    long hand:

    collectionView?.autoresizingMask = NSAutoresizingMaskOptions([NSAutoresizingMaskOptions.ViewWidthSizable,NSAutoresizingMaskOptions.ViewMaxXMargin,NSAutoresizingMaskOptions.ViewMinYMargin,NSAutoresizingMaskOptions.ViewHeightSizable,NSAutoresizingMaskOptions.ViewMaxYMargin])
    

    or short hand:

    collectionView?.autoresizingMask = NSAutoresizingMaskOptions([.ViewWidthSizable,.ViewMaxXMargin,.ViewMinYMargin,.ViewHeightSizable,.ViewMaxYMargin])
    
    0 讨论(0)
提交回复
热议问题