user10375884
user10375884

Reputation:

Unable to create instance of a resuable view

I am using this code:

import UIKit

class SnackBarView: UIView {

    @IBOutlet var containerView: UIView!

    @IBOutlet var labelText: UILabel!


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

        let _ = commonInitialization()

    }


    func commonInitialization() -> UIView
    {
        let bundle = Bundle.init(for: type(of: self))
        let nib = UINib(nibName: "SnackBarView", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
        return view

    }

}

when I try initialising it like this:

let snackBar = SnackBarView()

it gives the error:

Missing argument for parameter 'coder' in call

I know there is something wrong in the init function but I am not sure how to correct this. How should I proceed correcting this?

Upvotes: 0

Views: 56

Answers (3)

dniswhite
dniswhite

Reputation: 176

The error is not in your class but rather in how you are attempting to call it.

Since you want to create the UIView with zero (0) parameters you need to supply it a constructor (init) to deal with that situation when it happens.

Hopefully the below will work to give you a constructor with zero (0) parameters.

class SnackBarView: UIView {

    @IBOutlet var containerView: UIView!

    @IBOutlet var labelText: UILabel!


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

        let _ = commonInitialization()
    }

    // you need to add this init
    override init(frame: CGRect) {
        super.init(frame: frame)

        // call your custom initialization code here
        let _ = commonInitialization()
    }

    // constructor with zero (0) parameters
    convenience init() {
        // call the override from above with a default CGRect
        self.init(frame: CGRect.zero)
    }

    func commonInitialization() -> UIView
    {
        let bundle = Bundle.init(for: type(of: self))
        let nib = UINib(nibName: "SnackBarView", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
        return view
    }
}

Upvotes: 2

Shehata Gamal
Shehata Gamal

Reputation: 100541

I think it's meaningless to create a UIView with xib , and then add an instance of the same type to it as commonInitialization here occupies all frame of itself , I think you need

class SnackBarView: UIView {

    @IBOutlet var containerView: UIView!

    @IBOutlet var labelText: UILabel!

    class  func commonInitialization(_ rec:CGRect) -> SnackBarView
    {

        let nib = UINib(nibName: "SnackBarView", bundle: nil)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! SnackBarView
        view.frame = rec
        return view

    }

}

//

let v = SnackBarView.commonInitialization(view.frame)

view.addSubview(v)

Upvotes: 0

Jogendar Choudhary
Jogendar Choudhary

Reputation: 3494

You need to add override init(frame: CGRect) in your view: updated code is below:

class SnackBarView: UIView {

    @IBOutlet var containerView: UIView!

    @IBOutlet var labelText: UILabel!


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

        let _ = commonInitialization()

    }

    // you need to add this init
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    func commonInitialization() -> UIView
    {
        let bundle = Bundle.init(for: type(of: self))
        let nib = UINib(nibName: "SnackBarView", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
        return view

    }

}

Upvotes: 0

Related Questions