This question is related to this answer. Check both.
Failed to render instance of ClassName: The agent threw an exception loading nib in bundle
Bottom Line
Make sure that your xib file does not have any orphaned outlets. Check each view/element of the nib for an outlet and remove and re-add.
For me, they were orphaned outlets. It seems the nibs and IB are very finicky and the debugger doesn't give many details... if you can't get this to work, you might start with a fresh nib/xib file.
Walkthrough of my working code
This issue took me several days to resolve. For the benefit of others I am giving a verbose answer and showing all of my relevant code and connections.
A working commit where I implemented the fix action (above) is here:
https://github.com/jfosterdavis/ZMAppFoundation/commit/6855f0d5b9cd1bc320395e57e2b271653ef7acd1
Xcode version 9.2
My file structure
Here is my file structure (note: I am creating a pod with cocoapods named ZMAppFoundation
. Also, ZMPieTimerView.swift
is not relevant to the solution.):
I want my nib to be viewable (IBDesignable) in the Main.storyboard
file. Here is the File's Owner and Custom Class of my xib, ZMGauge.xib
:
Code, implementations
Here is my ZMXibView class:
// Adapted from https://medium.com/zenchef-tech-and-product/how-to-visualize-reusable-xibs-in-storyboards-using-ibdesignable-c0488c7f525d
import UIKit
@IBDesignable
open class ZMXibView: UIView {
var contentView:UIView?
@IBInspectable var nibName:String?
override open func awakeFromNib() {
super.awakeFromNib()
xibSetup()
}
func xibSetup() {
guard let view = loadViewFromNib() else { return }
view.frame = bounds
view.autoresizingMask =
[.flexibleWidth, .flexibleHeight]
addSubview(view)
contentView = view
}
func loadViewFromNib() -> UIView? {
guard let nibName = nibName else { return nil }
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(
withOwner: self,
options: nil).first as? UIView
}
override open func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
xibSetup()
contentView?.prepareForInterfaceBuilder()
}
}
In storyboard, my xib is designated in the Custom Class. I am using cocoapods to develop a pod. I have explicitly selected the Module. (Note that in my XibView class, I have to define the nibName
property.):
Don't Forget!
Then you may need to clean, close Xcode, rebuild, or simply wait a while for the IB to render it again. It is still a mystery to me exactly when Xcode will decide to try to render the IBDesignables, and I don't know of a way to force.
Success
Based on my code and the actions I took, my nib is now IBDesignable viewable in my Main.storyboard.
In case you missed it
In case you missed it, my solution is at the very top of this post. I got mine to clear the error cited by the OP by removing some orphaned IBOutlets.