Generic IBDesginables UIView extension
Asked Answered
J

1

1

I would like to create generic extension for class to add some designables functionality to any UIView subclass and by this avoid adding functionality to all subclasses. So, would be nice to add extension for UIView which conforms to protocol SomeProtocol (It's empty because it is just a tag to mark classes which I want functionality to be added). Then just add that protocol in any UIView subclass where I want that functionality to be implemented like this:

protocol SomeProtocol {
  //empty
}

class BCBorderedView : UIView, SomeProtocol
{
  //empty
}

class BCBorderedSearch: UISearchBar, SomeProtocol
{
  //empty
}

My implementation below receives error with message

"Trailing 'where' clause for extension of non-generic type 'UIView'"

@IBDesignable
extension UIView where Self:SomeProtocol //Error: Trailing 'where' clause for extension of non-generic type 'UIView'
{

  @IBInspectable
  public var cornerRadius: CGFloat
  {
      set (radius) {
          self.layer.cornerRadius = radius
          self.layer.masksToBounds = radius > 0
      }

      get {
          return self.layer.cornerRadius
      }
  }

  @IBInspectable
  public var borderWidth: CGFloat
  {
      set (borderWidth) {
          self.layer.borderWidth = borderWidth
      }

      get {
          return self.layer.borderWidth
      }
  }

  @IBInspectable
  public var borderColor:UIColor?
  {
    set (color) {
        self.layer.borderColor = color?.cgColor
    }

    get {
        if let color = self.layer.borderColor
        {
            return UIColor(cgColor: color)
        } else {
            return nil
        }
    }
  }
}

Removing where clause compiles and works, but it adds functionality to all UIViews and it's subclasses (basically all UI elements) which make IB agent crash from time to time in storyboard.

Any ideas how this plan can be updated to work?

Jailhouse answered 22/6, 2017 at 17:9 Comment(0)
F
3

extension Foo where ... can only be used if Foo is

  • a generic class or structure
  • a protocol containing some associated types
  • a protocol where we extend with a default implementation for when Self is of a specific (object/reference) type, or conforms to some type constraint.

Trailing 'where' clause for extension of non-generic type 'UIView'

The above error implies that UIView is a non-generic class type, and so where clause cannot be applied here.

So, rather than attempting to extend UIView, you must extend SomeProtocol with a default implementation for cases where Self: UIView

Your extension should extend functionality to all types that conform to SomeProtocol and are of type UIView

In a nutshell, you should switch the order in the extension clause. So,

extension UIView where Self : SomeProtocol

should be

extension SomeProtocol where Self: UIView
Ferriage answered 22/6, 2017 at 21:57 Comment(4)
but then I can't use IBDesignables, right? :/ The main idea of this extension was to make unified designables declaration and avoid code duplicationJailhouse
And I still would have to duplicate code all over the place which actually achieves nothing. So You didn't actually answer the question of this postJailhouse
Well, I guess original intent of the question was to know the cause of the error you were getting. I did provide answer to that part of the question with clear explanation. I tried to help you with your query and I believe I did that right. Thanks anyways.Ferriage
In case it helps " IBDesignable works fine for subclasses, but not for extensions". #29907355Ferriage

© 2022 - 2024 — McMap. All rights reserved.