Search code examples
iosswiftuiappearance

What Swift property types are allowed in UIApperance compliant custom classes?


I recently tried with no success to add a UIApperance compliant property to one of my Swift classes (ScoreView). You can see the relevant code below:

private var gaugeThresholds = Array<GaugeThreshold?>(repeating: nil, count: ScoreView.maxGaugeIntervals)

public func gaugeThreshold(forInterval interval: Int) -> GaugeThreshold? {
    return (0 <= interval && interval < ScoreView.maxGaugeIntervals) ? self.gaugeThresholds[interval] : nil
}

public func setGaugeThreshold(_ threshold: GaugeThreshold, forInterval interval: Int) {
    if 0 <= interval && interval < ScoreView.maxGaugeIntervals {
        self.gaugeThresholds[interval] = threshold
    }
}

where GaugeThreshold is a Swift struct:

public struct GaugeThreshold {
    let until: Float
    let color: UIColor

    public init(until: Float, color: UIColor) {
        self.until = until
        self.color = color
    }
}

This was failing miserably, and the only reason I can think of for this to fail is the fact that I'm using a custom type for the property instead of one of the standard types.

According to UIAppearanceContainer documentation: The property type may be any standard iOS type: id, NSInteger, NSUInteger, CGFloat, CGPoint, CGSize, CGRect, UIEdgeInsets or UIOffset. But if you browse the list of methods and properties conforming to UIAppearance as of iOS 8.0, you can see there are other types that are working properly as UIImage, UIColor... so does anybody know what makes a type valid for being used as a UIAppearance property?


Solution

  • Of course, nothing like posting to StackOverflow to find out the answer five minutes later. It turns out the key is the id type. Changing

    public struct GaugeThreshold { ...
    

    to

    public class GaugeThreshold: NSObject { ...
    

    did the trick.