iosswiftibdesignable

IBInspectable not updating in storyboard but works on simulator


I can view the changes made using IBInspectable on my simulator but not in my storyboard

I tried reinstalling my Xcode but it didn't fix this issue. Here are some screenshots :

Storyboard

Simulator

So i know my code works fine because it runs in the simulator and this is a new project altogether so I do not have any of the "Storyboard might still be loading the changes" problems.

import UIKit

extension UIView {

@IBInspectable
var cornerRadius: CGFloat {
    get {
        return layer.cornerRadius
    }
    set {
        layer.cornerRadius = newValue
        layer.masksToBounds = newValue > 0
    }
}

@IBInspectable
var borderWidth: CGFloat {
    get {
        return layer.borderWidth
    }
    set {
        layer.borderWidth = newValue
    }
}

@IBInspectable
var borderColor: UIColor? {
    get {
        let color = UIColor(cgColor: layer.borderColor!)
        return color
    }
    set {
        layer.borderColor = newValue?.cgColor
    }
}

@IBInspectable
var shadowRadius: CGFloat {
    get {
        return layer.shadowRadius
    }
    set {
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowOpacity = 0.4
        layer.shadowRadius = shadowRadius
    }
}
}

Solution

  • Firstly, you need @IBDesignable directive to render the updates in Storyboard whereas @IBInspectable is only to access the property directly in the Storyboard.

    Secondly, you have extended the UIView class to show the inspectable properties in the Storyboard but without @IBDesignable.

    Now you would think adding @IBDesignable would solve your problem but sadly you can't apply @IBDesignable on an extension like so:

    @IBDesignable //won't work on an extension
    extension UIView {
        //...
    }
    

    You can only apply the @IBDesignable directive on a class you have access to, like so:

    @IBDesignable
    class MyPrettyDesignableView: UIView {
        //...
    }
    

    Solution:

    Bottomline is that you should subclass UIView and apply the @IBDesignable directive on this class.
    Basically, your only option is:

    @IBDesignable
    class MyPrettyDesignableView: UIView {
        
        @IBInspectable var cornerRadius: CGFloat = 0 {
            didSet {
                self.layer.cornerRadius = cornerRadius
                self.layer.masksToBounds = true
            }
        }
        
        @IBInspectable var borderWidth: CGFloat = 0 {
            didSet {
                self.layer.borderWidth = borderWidth
            }
        }
        
        @IBInspectable var borderColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) {
            didSet {
                self.layer.borderColor = borderColor.cgColor
            }
        }
        
    }
    

    Then in the storyboard, go to the view that you want designable in storyboard and change it's custom class to MyPrettyDesignableView.

    1. Change it's custom class to your IBDesignable subclass: IBDesignable

    2. Set the IBInspectable properties: IBInspectable