iosswiftswift3ibinspectableoptionsettype

Create a OptionSet that is usable with IBInspectable


I'm trying to create a OptionSet which can be used in combination with @IBInspectable It seems like this was possible in Swift 2.2

I came across this library which seems to be using an OptionSet in combination with @IBInspectable (The IBInspectable is being the first one set and the structure is actually created on the bottom of the class)

I think it was possible because of the BooleanType which seems to be removed since Swift 2.3

I wrote my OptionSet like this but it doesn't work in combination with @IBInspectable because it's not supported where the BooleanType was (I think that is why it did work in the code of the earlier mentioned library)

public struct Shapes: OptionSet {
    private enum Shape: Int, CustomStringConvertible {
        case Circle=1, Square=2

        public var description: String {
            var shift = 0
            while (rawValue >> shift != 1) { shift += 1 }
            return ["Circle", "Square"][shift]
        }
    }
    public let rawValue: Int
    public init(rawValue: Int) { self.rawValue = rawValue }
    private init(_ shape: Shape) { self.rawValue = shape.rawValue }

    static let Circle = Shapes(Shape.Circle)
    static let Square = Shapes(Shape.Square)
}

Does anyone know how to make sure that it will work in Swift 3


Solution

  • So I did find a way to be able to use it by writing some sort of adapter.

    I'm pretty sure it can be done better and if anyone has a way to do so don't hesitate to provide your solution but this is how I did it right now

    public struct Corners: OptionSet {
    private enum Corner: Int, CustomStringConvertible {
        case TopLeft=1
        case TopRight=2
        case BottomLeft=4
        case BottomRight=8
        case All=16
    
        public var description: String {
            var shift = 0
            while (rawValue.hashValue >> shift != 1) { shift += 1 }
            return ["topleft", "topright", "bottomleft", "bottomright", "all"][shift]
        }
    }
    public let rawValue: Int
    public init(rawValue: Int) { self.rawValue = rawValue }
    private init(_ shape: Corner) { self.rawValue = shape.rawValue }
    
    static let TopLeft = Corners(Corner.TopLeft)
    static let TopRight = Corners(Corner.TopRight)
    static let BottomLeft = Corners(Corner.BottomLeft)
    static let BottomRight = Corners(Corner.BottomRight)
    static let All = [TopLeft, TopRight, BottomLeft, BottomRight]
    }
    
    // Needed to split the string that's provided in the @IBInspectable. and remove any possible spaces the user introduced
    extension String {
        func getStrings() -> [String] {
            var stringArray: [String] = []
            let strings = self.characters.split{$0 == ","}.map(String.init)
            for s in strings {
                let string = s.removeSpaces()
                stringArray.append(string)
            }
            return stringArray
        }
    
        func removeSpaces() -> String {
            if self.characters.first == " " {
                var copy = self
                copy.characters.removeFirst()
                return copy.removeSpaces()
            } else {
                return self
            }
        }
    }
    

    Then my @IBInspectable looks like this

    var corners = [Corners.TopLeft]
    @IBInspectable public var onCorners: String = "" {
        willSet {
            corners = []
            for s in newValue.lowercased().getStrings() {
                switch s {
                    case "topleft":
                        corners.append(Corners.TopLeft)
                    case "topright":
                        corners.append(Corners.TopRight)
                    case "bottomleft":
                        corners.append(Corners.BottomLeft)
                    case "bottomright":
                        corners.append(Corners.BottomRight)
                    case "all":
                        corners = Corners.All
                    default:
                        return
                }
            }
        }
        didSet {
            // Do your logic here
        }
    }