Swift multiple inheritance solution for IBInspectable/IBDesignable?

1.1k views Asked by At

I've been playing with the IBInspectable/IBDesignable like in this article: http://nshipster.com/ibinspectable-ibdesignable/.

It shows how you can make an extension to add extra editing options in storyboard. The problem however is that you can't see these changes reflected in the preview. For this you need to subclass, use IBDesignable and do the didset{} stuff.

The problem with this is that you need to make a subclass of every stock UIView subclass. So a subclass of UILabel, UITextField and so on. Every time you have to copy/paste the regular UIView stuff like borders and corner radius.

I don't believe Swift supports multiple inheritance, which would have made this much easier.

Let's say your IBDesignable subclass of UIView is called IBView. Is there a way to make e.g. UILabel be a subclass of IBView instead of UIView?

In the end I'm looking if there is a way to make IBDesignable less tedious.

1

There are 1 answers

0
Roberto Sampaio On

Like you, I'm trying to find a better solution to work with IBDesignable.

What I did to avoid repeat the same code:

  1. I made an extension of UIView to insert all the @IBInspectables I want (like corder radius, border width...).
  2. I created my @IBDesignables that only inherit from UIView, UIButton (or any subclass of UIView I want) in order to render on Interface Builder.

Check this code:

extension UIView {

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

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor ?? UIColor.clear.cgColor)
        }

        set {
            layer.borderColor = newValue?.cgColor
        }
    }

    @IBInspectable var borderWidth: Double {
        get {
            return Double(layer.borderWidth)
        }

        set {
            layer.borderWidth = CGFloat(newValue)
        }
    }
}

@IBDesignable
class BorderView: UIView { }

@IBDesignable
class BorderButton: UIButton { }

I hope it helps you!