2

I try to implement Custom Loader View with Nib file. But I get an error in loadViewFromNib() at

return nib.instantiate(withOwner: self, options: nil).first as? UIView.

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffee6f3df98)

open class LoaderView: UIView {

@IBOutlet var loaderImage: UIImageView!    
@IBOutlet var contentView: UIView!

func xibSetup() {
    contentView = loadViewFromNib()
    contentView.frame = bounds
    contentView.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
    addSubview(contentView)
}

required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    xibSetup()
}

override init(frame: CGRect) {
    super.init(frame: frame)
    xibSetup()
}

func loadViewFromNib() -> UIView? {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "LoaderView", bundle: bundle)
    return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}

I call this loader in VC in viewDidLoad() as

let loader = LoaderView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
view.addSubview(loader)

Vinod Kumar
  • 3,375
  • 1
  • 17
  • 35
Ali Ural
  • 93
  • 1
  • 13

2 Answers2

4

Your code is fine there is no recursion

Please make sure you have

1) Double check your IBOUtlet connection

2) Added Your class in File's Owner


enter image description here

enter image description here

I have created This same as your code

class CustomView: UIView {

    let nibName = "CustomView"
    @IBOutlet var view : UIView!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetUp()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetUp()
    }

    func xibSetUp() {
        view = loadViewFromNib()
        view.frame = self.bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
    }

    func loadViewFromNib() -> UIView {

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "CustomView", bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as! UIView

    }

}

Have look at output

enter image description here

Prashant Tukadiya
  • 15,838
  • 4
  • 62
  • 98
  • I am sure about that the IBOutlet and Xib connection in Files Owner. Your code is same. But still not working. I dont use storyboard for VC. Is there any problem at there ?. – Ali Ural Jul 05 '18 at 10:03
  • @AliUral Make sure your xib is added In target membership (Build phase check copy bundle resource). Also Clean derived data + clean project or restart xcode – Prashant Tukadiya Jul 05 '18 at 10:06
  • I added an image – Ali Ural Jul 05 '18 at 10:10
  • @AliUral That's wrong !! , Remove Loader from there and add to File's owner , Check yellow box top on it where file's owner written – Prashant Tukadiya Jul 05 '18 at 10:12
  • Thanks Dude . The problem is solved. But can you explain why we put in there. Normally when I create a Xib File , I decleare class name from Element not File's Owner. Is it wrong ? – Ali Ural Jul 05 '18 at 10:20
  • @AliUral Check this https://stackoverflow.com/questions/15150713/confused-difference-between-custom-class-for-an-object-and-for-the-files-owner – Prashant Tukadiya Jul 05 '18 at 10:30
  • 2
    Thanks bro. I give ur star :) – Ali Ural Jul 05 '18 at 10:31
2

You have recursion in

required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    xibSetup()
}

You call loadViewFromNib() in xibSetup(), it call UINib(nibName: "LoaderView", bundle: bundle), that call required public init?(coder aDecoder: NSCoder)

developer.apple.com

Alexey Kudlay
  • 525
  • 2
  • 14