Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IB Designables: Failed to render and update auto layout status

I have a custom view (xib) that has a UIButton inside of it, I made id IBDesignable doing the following:

UserView.swift

import UIKit

@IBDesignable
class UserView: UIView {

    @IBOutlet var view: UIView!
    @IBOutlet weak var userButton: UIButton!

    override init(frame: CGRect) {
        super.init(frame: frame)
        load()

    }

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

    fileprivate func load() {
        Bundle.main.loadNibNamed("UserView", owner: self, options: nil)
        addSubview(view)
        self.frame = bounds
    }

}

UserView.xib

  • Added the UIButton and set constraints
  • Set the File's Owner: UserView

Storyboard

I added a UIView to a Bar Button Item and assigned UserView class but nothing is rendering, and I got the following build error:

error: IB Designables: Failed to render and update auto layout status for FoodViewController (bR3-Kz-wX7): The agent threw an exception.

My currently environment: Xcode 9, Swift 4

like image 451
Jonathan Solorzano Avatar asked Oct 13 '17 06:10

Jonathan Solorzano


4 Answers

I just had the exact same issue, and the only thing that worked for me was instead of using the main Bundle I had to get the Bundle for the Nib I wanted. Essentially changing:

Bundle.main.loadNibNamed("UserView", owner: self, options: nil)

To:

let bundle = Bundle(for: UserView.self)
bundle.loadNibNamed("UserView", owner: self, options: nil)

Which is bizarre, as in my case when comparing the two Bundles at runtime in LLDB they were identical (class name is different but the rest of my setup was identical to the OP)

lldb screenshot Updated

Why loading NIB from main bundle does not work?

Because when InterfaceBuilder is rendering it is not running the application. There is no "main application bundle".

like image 124
Mike Velu Avatar answered Oct 17 '22 07:10

Mike Velu


I add this script at the end of my Podfile and performed pod install again. So I could build normally my project.

post_install do |installer|
    installer.pods_project.build_configurations.each do |config|
        config.build_settings.delete('CODE_SIGNING_ALLOWED')
        config.build_settings.delete('CODE_SIGNING_REQUIRED')
    end
end
like image 33
Haroldo Gondim Avatar answered Oct 17 '22 08:10

Haroldo Gondim


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.

A nib subview with an outlet

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.):

enter image description here

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:

File's Owner Custom Class

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.):

Setting custom class on the xib

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.

nib is viewable now

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.

like image 6
Jacob F. Davis C-CISO Avatar answered Oct 17 '22 07:10

Jacob F. Davis C-CISO


Xcode 9.3, CocoaPods 1.5.3 It may be due to recent update on CocoaPods version. See issue here.

I had this error IB Designables: Failed to render and update auto layout status in the storyboard, the class STPPaymentCardTextField in Stripe SDK related to Cocoapods.

Solution is to downgrade your CocoaPods to 1.4.0.

sudo gem list cocoapods

sudo gem uninstall cocoapods

sudo gem install cocoapods -v 1.4.0

pod update
like image 6
Cons Bulaquena Avatar answered Oct 17 '22 07:10

Cons Bulaquena