Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
    }
}
}
like image 964
Ashutosh Sultania Avatar asked Feb 28 '18 06:02

Ashutosh Sultania


1 Answers

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

like image 106
staticVoidMan Avatar answered Sep 18 '22 02:09

staticVoidMan