Swift - Changing UIView programmatically while keeping IBOutlets (File's Owner)

1.4k Views Asked by At

Here is a rough sketch to help understand what I'm trying to do: enter image description here

I have a MainViewController that has a single UIView (MainView)

I have a .xib UIView (called Window) that contains two controls:

  1. segmentedController - with four segments
  2. UIView (called WindowUIView) - that will change depending upon the segment that is chosen

There are also four independent .xib UIViews (each with their own IBOutlets and IBActions) that will load into the WindowUIView (which subsequently loads into the MainViewController's UIView).

When 'Option 1' is chosen from the segmentedController I would like to load Option1UIView into the WindowUIView and execute the code contained within Option1UIView.swift.

When 'Option 2' is chosen from the segmentedController I would like to load Option2UIView into the WindowUIView and execute the code contained within Option2UIView.swift.

etc etc etc for Option 3 & Option 4

So far, I have successfully connected the File's Owner -> Custom Class -> Class fore each one of the Option#UIViews (in their *.xib) to the appropriate Option#UIView.swift

The MainViewController has its MainView Custom Class -> Class set to Window The Window.xib has its WindowUIView Custom Class -> Class set to Window The Window's UIView (WindowUIView) File's Owner -> Custom Class -> Class is set to Option1UIView

When the app is run in the simulator, things work as expected: MainViewController has its MainView changed to the Window's, which in turn has its view changed to Option1UIView. All of the IBOutlets and IBActions are working properly for Option1UIView.

However, when I chose a different segment, the appropriate Option#UIView is loaded in WindowUIView (good), but the code is no longer connected. The app crashes because the .xib files are unable to find the connections (IBOutlets & IBActions) in their respective files (*.swift) that used to be attached to the File's Owner. It's as if the File's Owner has been deleted.

What am I doing wrong? Here is the error: this class is not key value coding-compliant for the key View (from the Option#UIView swift file).

Update: Here is the code inside Window.swift

class Window: UIView {
@IBOutlet var View: UIView! // Full view
@IBOutlet weak var Controller: UISegmentedControl!
@IBOutlet var View: WindowUIView! // The subView

required init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder)
    NSBundle.mainBundle().loadNibNamed("Window", owner: self, options: nil)
    self.addSubview(self.View)
}

@IBAction func controllerSwitch(sender: AnyObject) {
    let value = Controller.selectedSegmentIndex
    switch value {
        case 0 : print("Option1")
            NSBundle.mainBundle().loadNibNamed("Option1UIView", owner: self, options: nil)
            self.WindowUIView.addSubview(self.View)
        case 1 : print("Option2")
            NSBundle.mainBundle().loadNibNamed("Option2UIView", owner: self, options: nil)
            self.WindowUIView.addSubview(self.View)
        case 2 : print("Option3")
            NSBundle.mainBundle().loadNibNamed("Option3UIView", owner: self, options: nil)
            self.WindowUIView.addSubview(self.View)
        case 3 : print("Option4")
            NSBundle.mainBundle().loadNibNamed("Option4UIView", owner: self, options: nil)
            self.WindowUIView.addSubview(self.View)

        default : print("Out of bounds")
    }
}

I also have an extension to help load the Nib files:

extension UIView
{
    class func loadNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> UIView? {
        return UINib(
            nibName: nibNamed,
            bundle: bundle
            ).instantiateWithOwner(nil, options: nil)[0] as? UIView
    }
}
0

There are 0 best solutions below