简体   繁体   中英

UIImageView outlet nil in custom UIView with xib

I've created a custom UIView with multiple IBOutlets including a UIImageView, and three UILabel s. Despite setting the image value in the awakeFromNib() function, I'm still getting a nil value for the outlet when attempting to set it. The UIView was constructed using a custom xib file.

I put the set operation in awakeFromNib() so as to assure the outlets had been initialized prior to setting them, yet this failed to help. I'm not sure if it's an issue with the xib file as I've only ever used custom xibs when making a custom table cell, so perhaps the issue is rooted there?

class VotingCard: UIView {
    @IBOutlet weak var proPicImg: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var hometownLabel: UILabel!
    @IBOutlet weak var ratingLabel: UILabel!

    var proPic = UIImage()
    var name = ""
    var hometown = ""
    var rating = 0.0

    init(pic: UIImage, rush: Rush) {
        proPic = pic
        name = rush.fullName
        hometown = rush.homeTown
        rating = rush.compositeRating
        super.init(frame: CGRect(x: 0, y: 0, width: 250, height: 300))
    }

    override func awakeFromNib() {
        proPicImg.image = proPic
        nameLabel.text = name
        hometownLabel.text = hometown
        ratingLabel.text = "\(rating)"
    }

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

I should view a simple card with the profile image and respective data visible, yet instead it crashes.

EDIT

NIB-based development is sort-of deprecated:

For iOS developers, using storyboards is the recommended way to design user interfaces.

https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/NibFile.html

But, looks like you're missing this step:

At runtime, you load a nib file using the method loadNibNamed:owner: or a variant thereof. The File's Owner is a placeholder in the nib file for the object that you pass as the owner parameter of that method. Whatever connections you establish to and from the File's Owner in the nib file in Interface Builder are reestablished when you load the file at runtime.

See as an example:

https://medium.com/@umairhassanbaig/ios-swift-creating-a-custom-view-with-xib-ace878cd41c5

If you want to do it the recommended way with Storyboard (apparently not, but this is for general audience):

https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html

viewDidLoad()—Called when the view controller's content view (the top of its view hierarchy) is created and loaded from a storyboard. The view controller's outlets are guaranteed to have valid values by the time this method is called. Use this method to perform any additional setup required by your view controller.

So with the UIViewController method, put your code in viewDidLoad() instead.

Keep in mind this is always called, so this will overwrite the work of your custom init() function. Perhaps this is what you were running into.

I would refactor it to avoid ugly code. Create the Rush object always (declare as Optional as stored property), but initialize it in awakeFromNib() for the XIB case, and copy the input object in the custom-init case.

Then viewDidLoad() has no conditionals.

Your problem is either

1-The imageView isn't connected to Ib , and the fix is to connect it

Or

2- You create an object of the view with init(pic: UIImage, rush: Rush) { and that for sure won't load the UI with view , hence all outlets are nil , and the fix to add this method

class func getInstance(_ pic: UIImage, rush: Rush) -> VotingCard { 
   let v = Bundle.main.loadNibNamed("VotingCard", owner: self, options: nil)!.first as! VotingCard 
   v.proPic = pic
   v.name = rush.fullName
   v.hometown = rush.homeTown
   v.rating = rush.compositeRating
   return v
}

Call

let v = VotingCard.getInstance(<#image#>,rush:<#rush#>)
v.frame = // set some frame
// ready for use

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM