Appearance proxies / UI_APPEARANCE_SELECTOR in Swift?
The Apple documentation states:
To participate in the appearance proxy API, tag your appearance property selectors in your header with UI_APPEARANCE_SELECTOR.
In Objective-C one can annotate properties with UI_APPEARANCE_SELECTOR
like this:
@property (nonatomic, strong) UIColor *foregroundColor UI_APPEARANCE_SELECTOR;
How can I do the same in Swift?
Mark your custom view property as dynamic
.
For example:
class YourCustomView: UIView {
@objc dynamic var subviewColor: UIColor? {
get { return self.yourSubview.backgroundColor }
set { self.yourSubview.backgroundColor = newValue }
}
...
}
Then:
YourCustomView.appearance().subviewColor = UIColor.greenColor()
I did not find the solution but a workaround. Instead of annotating the properties I made them as a class variable.
private struct StarFillColor { static var _color = UIColor.blackColor() }
internal class var starFillColor: UIColor {
get { return StarFillColor._color }
set { StarFillColor._color = newValue }
}
And in the file where I setup all my appearances:
MyClass.starFillColor = UIColor.r(181, g: 60, b: 109)
I hope it will help somebody!
Based on previous answers, here is the extension to UIView I implemented to manage UIView appearance with view borders, I hope it can help someone :
extension UIView {
@objc dynamic var borderColor: UIColor? {
get {
if let color = self.layer.borderColor {
return UIColor(cgColor: color)
} else {
return nil
}
}
set(color) {
self.layer.borderColor = color?.cgColor
}
}
@objc dynamic var borderWidth: NSNumber? {
get { return NSNumber(value: Float(self.layer.borderWidth))}
set(width) {
self.layer.borderWidth = CGFloat(width?.floatValue ?? 0)
}
}
@objc dynamic var cornerRadius: NSNumber? {
get { return NSNumber(value: Float(self.layer.cornerRadius))}
set(radius) {
self.layer.cornerRadius = CGFloat(radius?.floatValue ?? 0)
}
}
}
In Swift, you don't need (actually, you cannot) to annotate properties with UI_APPEARANCE_SELECTOR
.
Just make sure your appearance property accessor methods be of the form:
func propertyForAxis1(axis1: IntegerType, axis2: IntegerType, axisN: IntegerType) -> PropertyType func setProperty(property: PropertyType, forAxis1 axis1: IntegerType, axis2: IntegerType)
Source: Apple Documentation
For example:
func setStarViewColor(color: UIColor) {
self.backgroundColor = color
}
Then you can set your appearance property like this:
MyView.appearance().setStarViewColor(someColor)
I currently using this solution in my Swift project and it works, hope it's helpful to you too.