IB Designables: Failed to render and update auto layout status

后端 未结 14 1134
花落未央
花落未央 2020-12-13 04:11

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

UserView.swif

相关标签:
14条回答
  • 2020-12-13 04:46

    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.

    0 讨论(0)
  • 2020-12-13 04:50

    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
    
    0 讨论(0)
  • 2020-12-13 04:54

    For me, the fix came down to getting Interface Builder to redraw the object. I had this in two places and both were fixed by no changes to code but the symptoms of the agent error and the views being blank in storyboard was eventually fixed.

    One was fixed by dragging a UIView to a different order under the View and rebuilding. A second in a TableView with Prototype cell was fixed by selecting the TableView, changing the count of Prototype cells to two, wait a sec, then change it back to one. The TableView, which had been a white blank, then drew all the elements correctly and the agent error was gone.

    It feels like it's a bug with IB and from other searches, many solutions exist for the similar error. Hope this helps someone.

    0 讨论(0)
  • 2020-12-13 04:55

    XCode 11.6

    If you are using a UITableView & prototype cells, Select UITableView and in the attributes inspector, simply increase the count of Prototype cells. Then xcode will automatically build it again & will fix the issue. Once it is solved,reduce the count to previous value.

    0 讨论(0)
  • 2020-12-13 04:56

    I'm cringing at how dumb this is that doing what I'm about to tell you makes a difference, but you can try removing the breaking code out of

    override func prepareForInterfaceBuilder() {
    

    and only use it in

    override func awakeFromNib() {
    

    . I'm cringing, even more, when I report that its possible that your changes could still reflect in storyboard as desired when doing this.

    You can identify the breaking code by commenting out all the lines and using a process of elimination to identify the breaking line.

    0 讨论(0)
  • 2020-12-13 04:56

    For me this problem solved by,

    1. Updating pods.
    2. Changing build setting to '$(inherited)' for swift libraries embedded option.
    3. Building, cleaning, building.
    4. Closing project.
    5. Quitting Xcode.
    6. Running again.

    hahaha old hack :) Thanks!

    0 讨论(0)
提交回复
热议问题