76

When I write my own UIButton-extended class and make it @IBDesignable, I receive two errors in Interface Builder, namely:

  • Main.storyboard: error: IB Designables: Failed to update auto layout status: The agent crashed because the fd closed
  • Main.storyboard: error: IB Designables: Failed to render instance of RandjeUIButton: The agent crashed

Here is my code:

import UIKit

@IBDesignable
class RandjeUIButton: UIButton {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.backgroundColor = UIColor.blackColor()
    }
}

I am working in Xcode 7 beta 2 on OS X 10.11 beta 2. (Running in VM)

mathielo
  • 6,725
  • 7
  • 50
  • 63
jbehrens94
  • 2,356
  • 6
  • 31
  • 59
  • 11
    You need to override `init(frame: CGRect)` as well – Eric Qian Jul 07 '15 at 11:17
  • 3
    I have done that, the errors about the agent are dismissed now. I'm still seeing build failed in Interface Builder now when selecting the label in Identity inspector? – jbehrens94 Jul 07 '15 at 18:11
  • 1
    @EricQian I also override override init(frame : CGRect) and required init?(coder aDecoder: NSCoder) method. Still got the same error. – Raj Aggrawal Aug 23 '16 at 05:45

10 Answers10

127

Xcode's Interface Builder requires that you implement both or neither initializers for @IBDesignable classes to render properly in IB.

If you implement required init(coder aDecoder: NSCoder) you'll need to override init(frame: CGRect) as well, otherwise "the agent will crash" as seen in the errors thrown by Xcode.

To do so add the following code to your class:

override init(frame: CGRect) {
    super.init(frame: frame)
}
mathielo
  • 6,725
  • 7
  • 50
  • 63
  • 15
    I dont think so that is the reason. I have both methods, I am on 7.2. It is still crashing. – Alok C Apr 22 '16 at 20:16
  • 1
    This was the cause for me, I removed the `init(frame: CGRect)` because I was only initialising it from a storyboard. – Kyle Goslan Jul 23 '16 at 00:09
  • 3
    @mathielo I also override override init(frame : CGRect) and required init?(coder aDecoder: NSCoder) method. Still got the same error – Raj Aggrawal Aug 23 '16 at 05:49
  • 1
    It turned out to be a very hard debugging challenge for me. I was subclassing a class that was present in another framework (Pod). The parent class had one of the init methods without the public scope (default is internal). So, the init method was not visible in my source. Finally, figured this out, and made a copy of the parent class in my project's source. Thanks a lot! – K.K Sep 01 '16 at 08:27
  • 1
    This two init may not enough. Take UISegmentedControl as an example, you should also implement ***override init(items: [Any]?)***. – Bagusflyer May 29 '17 at 05:49
24

I've met the same problem and solved it this way:

  1. The Problem:

error: IB Designables: Failed to update auto layout status: The agent crashed

  1. Find the debug button in the inspection file and click it.

debug

  1. Then the Xcode will tell you where the prolem is. In my case I drop the IBDesignable before the class.

  2. Then I clean and rebuild it, the error disappeared

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Azure Yu
  • 397
  • 2
  • 5
  • Hi @Azure, I am facing the problem for that too. Xcode (7.3) is not moving me to the line of code what is causing the problem when I click on Debug button as you have shown nicely on the added image. Is that bug of Xcode? – Sauvik Dolui Jun 02 '16 at 08:49
  • Hi~Have you solved your problem now? I also use Xcode(7.3). Please make sure you choose the view which leads to the crash and click the debug button. – Azure Yu Jun 09 '16 at 10:27
  • 2
    Don't forget to **create an "All Exceptions" breakpoint** before clicking on the Debug button, this way the debugger will stop either a few instructions after the crash, where you could just click your code in the stack trace listing, or right at the instruction that's causing the crash. – carlos_ms Jul 10 '16 at 23:39
12

There are a myriad of problems that can cause this. Fire up Console, and look for the crash report IBDesignablesCocoaTouch...

I just sorted out a problem with a 3rd party designable which had issues with the valueForKey semantics.

voidref
  • 1,113
  • 11
  • 15
11

In Xcode 7.3, none of the above solutions worked for me, but the accepted answer to this question did: Failed to render instance of IB Designables

  1. Clear Xcode derived data for the project. They are in ~/Library/Developer/Xcode/DerivedData
  2. Clean your current build by pressing ⌘⇧K
  3. Build your project
  4. In storyboard go to Editor menu and do Refresh All Views; wait for build to be completed and errors should be gone

I did not need to do the 4th step to solve the problem (and get my PaintCode-drawRect'd UIView to paint in the storyboard), included here just in case.

Credit to @Mojtaba and @WeZZard

Community
  • 1
  • 1
Glenn Barnett
  • 2,031
  • 1
  • 21
  • 31
11

For me, it was not using #if !TARGET_INTERFACE_BUILDER that got me. Basically I had some code that would result in accessing a path in my Bundle...

Bundle.main.path(forResource: "Foo", ofType: "plist")

The problem is that when running in IB (and not in your app), Bundle.main isn't your app...

(lldb) po Bundle.main
NSBundle </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays> (loaded)

So the answer to this is simply to review your @IBDesignable UIView code carefully and use #if !TARGET_INTERFACE_BUILDER for anything (in my case calls to CoreLocation for example) that doesn't make sense when running at design time.

How I debugged and found this

This is what you see when using the Editor -> Debug Selected View while selecting your @IBDesignable UIView in your storyboard:

This is what you see when using the <code>Editor -> Debug Selected View</code> while selecting your <code>@IBDesignable UIView</code> in your storyboard

You'll then crash at the right location

The Debug Navigator

In my case, as you can see initXXXX was doing an assert, which was crashing at design time, because it was looking for a value in file in my Bundle — which is Xcode, at design time.

StuFF mc
  • 4,137
  • 2
  • 33
  • 32
10

I found something really important when using an UIImage in any class marked @IBDesignable. The classic UIImage init would crash the agent:

let myImage = UIImage(named: String) // crash the agent

The solution is to use this init method of UIImage:

let myImage = UIImage(named: String, in: Bundle, compatibleWith: UITraitCollection)

Working code example:

let appBundle = Bundle(for: type(of: self))
let myImage = UIImage(named: "myImage", in: bundle, compatibleWith: self.traitCollection))

Where self is your class with the @IBDesignable keyword. Xcode 9.4, Swift 4.1

Adrien Yvon
  • 662
  • 7
  • 18
9

XCode 10, Swift 4.2

I found an answer here

Solution was simple - changing the way the bundle was resolved in the required init?(coder aDecoder: NSCoder) method of my custom view class.

    Bundle.main.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)

needed to be changed to

let bundle = Bundle(for: TestView.self)
bundle.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)
escapedcanadian
  • 283
  • 5
  • 10
3

This is how I solves this problem:

  • Make sure the outlets are properly initialized
  • @IBInspectable properties would be properly initialized
  • in xib file, click on File's owner placeholder, Go to Identity inspector, make sure it wont have any default values

import UIKit

@IBDesignable class TestView: UIView {
    
    @IBOutlet weak var label: UILabel!
    
    
    @IBInspectable var textLabel1: String? {
        get {
            return label.text
        }
        set {
            label.text = newValue
        }
    }

    
    // MARK: Setup
    
    var view1: UIView!
    var nibName: String = "TestView"
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }
    
    private func xibSetup() {
        view1 = loadViewFromNib()
        
        view1?.frame = self.bounds
        view1?.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        
        if view1 != nil {
            addSubview(view1!)
            //textLabel1 = "ok"
        }
    }
    
    private func loadViewFromNib() -> UIView? {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: nibName, bundle: bundle)
        for object in nib.instantiateWithOwner(self, options: nil) {
            if let view: UIView = object as? UIView {
                return view
            }
        }
        return nil
    }
    
    
}

Usage:

enter image description here

vikram jeet singh
  • 3,416
  • 2
  • 21
  • 22
2

Just re-open a code on another Xcode setup System. In my case it Worked.

Charmi
  • 423
  • 1
  • 3
  • 9
  • This seems working on some cases. i was having the same issue tried all possible things which were not able to fix the issue, and finally i did closed the xcode completely and open another project which was not implementing any @IBDesignable, and opened the project on which agent was crashing and the error msgs are gone. i don't have any valid logic behind that but it seems xcode have some bog :( – dip Jan 16 '17 at 05:27
1

I wasted a full day on this and finally I got my problem solved enter image description here

I selected Build for target as 8.0 and it fixes everything for me.

Sam
  • 452
  • 5
  • 15