Reputation: 7960
I have a window with an outlet and a custom view (in my .xib
file) which contains a button and a text field. When a button is pressed in the window I want to add an instance of the custom view into the window.
Currently I have an outlet to the window and the custom view (configWindow
and customView
) and this action is called when the button is pressed:
@IBAction func addView(sender: NSButton) {
configWindow.contentView.addSubview(customView)
// Print the views in the window, see what's been added
for i in configWindow.contentView.subviews {
println(i)
}
}
This will only ever add one view to the window.
Is this the right way to go about it, or should I be using a completely different approach?
Upvotes: 1
Views: 1549
Reputation: 150605
You can't add the same view twice. It sounds like you are trying to add the same instance of customView
to configWindow
multiple times, which you can't do. If you think about it, it's fairly obvious why -- how will the superview manage two subviews which are the same? How will it know the difference between the two of them?
You should be adding different instances of the CustomView
class instead:
@IBAction func addView(sender: NSButton) {
let customView = CustomView(frame: <some frame>)
configWindow.contentView.addSubview(customView)
// Print the views in the window, see what's been added
for i in configWindow.contentView.subviews {
println(i)
}
}
Edited to add I've created an example project that you can download at https://bitbucket.org/abizern/so-27874883/get/master.zip
This basically initialises multiple views out of a nib file and adds them randomly to a view.
The Interesting part is:
class CustomView: NSView {
@IBOutlet weak var label: NSTextField!
class func newCustomView() -> CustomView {
let nibName = "CustomView"
// Instantiate an object of this class from the nib file and return it.
// Variables are explicitly unwrapped, since a failure here is a compile time error.
var topLevelObjects: NSArray?
let nib = NSNib(nibNamed: nibName, bundle: NSBundle.mainBundle())!
nib.instantiateWithOwner(nil, topLevelObjects: &topLevelObjects)
var view: CustomView!
for object: AnyObject in topLevelObjects! {
if let obj = object as? CustomView {
view = obj
break
}
}
return view
}
}
Where I create a factory method of the custom class that loads itself from the nib, and then returns the first top level object of the correct class.
Upvotes: 2