1

I have created a custom view (ImageAndToolBarContainerView) with a corresponding XIB file that I would like to load into multiple UIViewControllers in my app.

I have been hunting for a proper tutorial of how to do this, but almost every one I've come across either is too old or causes major exceptions.

When I try loading it through the story board / NIB, (I create a view in the UIViewController on the storyboard and I set the "Class" attribute to ImageAndToolBarContainerView. I Set the outlets, including the View, but none of them seem to load when the class is called, and I get the error :

fatal error: unexpectedly found nil while unwrapping an Optional value

when I try to access the view:

required init?(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder)
    //setup()
    self.view.frame = self.bounds
    self.addSubview(view)
}

Then, I try using the following code to load the NIB instead (by uncommenting the setup() function above. The code of setup is this:

func setup()
{
    self.loadViewFromNIB()
    self.view.frame = self.bounds
    self.addSubview(view)
}

func loadViewFromNIB() -> UIView
{
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: "ImageAndToolBarContainer", bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
}

That of course leads to an infinite loop.

I also have the following function declares:

override func awakeFromNib()
{
    super.awakeFromNib()
    self.view.frame = self.bounds
    self.addSubview(view)
}

What am I missing here? Where did I go wrong? Is there a definitive tutorial in how to do this properly?

pikovayadama
  • 808
  • 2
  • 8
  • 26
  • purely FWIW. really you should just be using a **container view** these days. it's sort of the "elephant in the room" with iOS programming. **everything** should just be a container view now. it's incredibly easy. Apple did it precisely to eliminate all the woes you mention. long tutorial http://stackoverflow.com/a/23403979/294884 – Fattie Dec 18 '15 at 17:52
  • Who's the File Owner of your custom view's .nib? And how are you creating your View Controllers? Are they coming from a Storyboard, or another .nib? – Bell App Lab Dec 18 '15 at 18:13
  • Seems like you are setting `ImageAndToolBarContainerView` in `Class` field of the `View` instead of set it in `File's Owner`. – eMdOS Dec 18 '15 at 18:24
  • Thank you, Joe, I will review that. In terms of File ownership, the nib's owner is ImageAndToolBarContainerView class. The View Controllers are created in the storyboard. **ImageAndToolBarContainerView** is set at the File Owner as well, and not in the class of the **View** – pikovayadama Dec 18 '15 at 18:31
  • Did you get to the bottom of this? I seem to be experiencing a similar problem! – Jason Apr 27 '16 at 20:39

2 Answers2

2

The infinite loop is probably caused because you set the File's Owner and also subclassed the View's class to your View's class name.

0xT0mT0m
  • 656
  • 5
  • 15
0

For anyone having this issue, if you register a Nib for a table or collection view, you are telling that parent view to go and load a nib named 'x' whenever it needs to dequeue a cell.

Normally with Nib code, you'll want a method to go and load the actual XML that makes your layout to tie it to the Nib class, but when you register a reusable view, your registration means that the parent view is responsible for doing this. It will literally go and load an XML file for you and try and tie that to a class when you cast it. By adding another loadViewFromNIB call inside of this will then cause an infinite loop to happen.

All you need to do is set the cell Nib's class to your custom class, register it and it will do the rest for you with reusable cells - remove the loadViewFromNIB method from any initialisers inside your cell and add registration code on the collection or table view class.

M3nd3z
  • 316
  • 2
  • 12