Load multiple instances of a NSView from Nib

721 views Asked by At

I was wondering if there was a method to create a view in a xib file and then connect its outlets to a class, so you can create multiple instances of that class and place them in the window. I have some problems, so can you help me fix my code?

Here's what I did:

Firstly I created 2 files: CustomView.xib and CustomView.swift. Then I designed the interface adding an NSImageView to the custom view. I set the file's owner to the class name and added an outlet from the NSImageView to the class.

Then I created the following function to load the interface from the nib:

func loadView() -> NSView {
    var top = NSArray()
    Bundle.main.loadNibNamed("CustomView", owner: self, topLevelObjects: &top)
    let view = top[0] as! NSView
    return view
}

And set up the class to load the interface:

override init(frame: CGRect) {
    super.init(frame: frame)
    let view = loadView()
    view.frame = bounds
    addSubview(view)
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

So I went on creating two variables of that class and placing it on the window:

var x = CustomView(frame: CGRect(x: 0, y: 0, width: 600, height: 105))
var y = CustomView(frame: CGRect(x: 0, y: 105, width: 600, height: 105))

And for some reasons this code gives me a strange error. It worked the first time, with one variable, but if I place more than one, it says it couldn't cast an NSWindow type in a NSView.

Could not cast value of type 'NSApplication' (0x7fffb5cf3ef0) to 'NSView' (0x7fffb5d04bb0).

enter image description here

I think that this error is given because sometimes the first top level object is the view, and sometimes it's the window. So I'm getting confused.

Obviously the error is thrown on this line:

let view = top[0] as! NSView

So what's the problem here?

(Please do not answer with cocoa touch code)

1

There are 1 answers

0
vadian On BEST ANSWER

Use the filter function to get the NSView instance

func loadView() -> NSView {
    var topLevelObjects = NSArray()
    Bundle.main.loadNibNamed("CustomView", owner: self, topLevelObjects: &topLevelObjects)
    let views = (topLevelObjects as Array).filter { $0 is NSView }        
    return views[0] as! NSView
}