Instantiate view from nib throws error

2019-04-03 19:00发布

I tried to make @IBDesignable UIView subclass following this (link) tutorial. First custom view goes fine. But when I try to make another one, I have errors. First I got failed to update auto layout status: the agent crashed and Failed to render instance of .... Somehow I started to be able to biuld and run project with these errors, but then I get new error - EXC_BAD_ACCESS ... on line let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView. Here is whole method:

func loadViewFromNib() -> UIView {

        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: "advancedCellView", bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView

        return view
    }

With first custom UIView is no problem. I use same code..

enter image description here

Any ideas? Thank you

4条回答
叼着烟拽天下
2楼-- · 2019-04-03 19:27

The loadViewFromNib() method you post looks fine, you're getting the bundle correctly and specifying the nib name as a string literal, so it should find the nib. As someone else commented, there's probably something wrong with your set up of the nib instead. Here are a few things to check:

  1. You should have AdvancedCellView set as the File's Owner Custom Class in the Identity Inspector.
  2. Check that the module is correct too - usually you just want it blank.
  3. The Custom Class for the View should not be set, just leave it as the default (UIView). If you have a more descriptive name than 'View' in the sidebar, it's probably wrong.
  4. Check that you only have one top level object in the nib. The sidebar should look like this, without any other entries, when you have the View tree collapsed.

Nib hierarchy with only one top level view

N.B. This answer is related to the tutorial that the OP linked to, and not the only correct way to set up a nib.

查看更多
别忘想泡老子
3楼-- · 2019-04-03 19:32

Try doing this instead. Always works for me:

let picker = NSBundle.mainBundle().loadNibNamed("advancedCellView", owner: nil, options: nil)
let view = picker[0] as! UIView

return view

Let me know if that works

查看更多
forever°为你锁心
4楼-- · 2019-04-03 19:33

The instantiateWithOwner(options:) method returns an array, not a view, so a forced downcast to UIView will never work. Instead, try casting to the actual type, [AnyObject].

The elements in the array correspond to top-level objects in the nib file, so the view you're interested in should be one of the array elements. Given the name of your nib file, in all likelihood there will only be one top-level object in the array -- the cell you're trying to load. Make sure that there's only one top-level object in the nib file, and that it is indeed an instance of a subclass of UIView.

Note that your implementation is potentially inefficient. If you're loading more than one cell, you should cache the UINib instance instead of creating a new one each time. Note that framework classes such as UITableViewController have built in methods for registering nibs that take care of these details automatically, so you may not actually need to do this yourself.

查看更多
不美不萌又怎样
5楼-- · 2019-04-03 19:35

I was looking at the tutorial and discovered that if you subclass the View element in your custom xib then you will get the error. Ensure you've only set the "File's Owner" to your custom class.

enter image description here

查看更多
登录 后发表回答