Swift 中的外观代理/UI_APPEARANCE_SELECTOR?
Posted
技术标签:
【中文标题】Swift 中的外观代理/UI_APPEARANCE_SELECTOR?【英文标题】:Appearance proxies / UI_APPEARANCE_SELECTOR in Swift? 【发布时间】:2014-10-02 22:17:38 【问题描述】:Apple 文档指出:
要参与外观代理 API,请标记您的外观 带有 UI_APPEARANCE_SELECTOR 的标题中的属性选择器。
在 Objective-C 中,可以像这样使用 UI_APPEARANCE_SELECTOR
注释属性:
@property (nonatomic, strong) UIColor *foregroundColor UI_APPEARANCE_SELECTOR;
如何在 Swift 中做同样的事情?
【问题讨论】:
【参考方案1】:将您的自定义视图属性标记为dynamic
。
例如:
class YourCustomView: UIView
@objc dynamic var subviewColor: UIColor?
get return self.yourSubview.backgroundColor
set self.yourSubview.backgroundColor = newValue
...
然后:
YourCustomView.appearance().subviewColor = UIColor.greenColor()
【讨论】:
我需要尝试一下。它是否记录在某处? 据我所知,它没有记录在案,但我试过了,它奏效了。基本上,从 Objective-C 框架动态访问的 Swift 属性应该被标记为动态的。 UI_APPEARANCE_SELECTOR 只是代码补全的编译器注解,对运行时没有影响。检查 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAppearance.h 不幸的是,它不适用于 Xcode 8.3.2 ios 9.1 中的 UIBarButton 子类,并且在我设置外观并实例化新的自定义 UIBarButtonSubclass 后导致 UIKit 崩溃 还需要在属性中添加@objc
属性才能生效。【参考方案2】:
我没有找到解决方案,但找到了解决方法。 我没有对属性进行注释,而是将它们作为类变量。
private struct StarFillColor static var _color = UIColor.blackColor()
internal class var starFillColor: UIColor
get return StarFillColor._color
set StarFillColor._color = newValue
在我设置所有外观的文件中:
MyClass.starFillColor = UIColor.r(181, g: 60, b: 109)
希望对大家有所帮助!
【讨论】:
【参考方案3】:根据以前的答案,这是我实现的 UIView 扩展,用于管理带有视图边框的 UIView 外观,我希望它可以帮助某人:
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)
【讨论】:
【参考方案4】:在 Swift 中,您不需要(实际上,您不能)用 UI_APPEARANCE_SELECTOR
注释属性。
只需确保您的外观属性访问器方法采用以下形式:
func propertyForAxis1(axis1: IntegerType, axis2: IntegerType, axisN: IntegerType) -> PropertyType func setProperty(property: PropertyType, forAxis1 axis1: IntegerType, axis2: IntegerType)
来源:Apple Documentation
例如:
func setStarViewColor(color: UIColor)
self.backgroundColor = color
然后你可以像这样设置你的外观属性:
MyView.appearance().setStarViewColor(someColor)
我目前在我的 Swift 项目中使用这个解决方案,它可以工作,希望它对你也有帮助。
【讨论】:
嗨,你能把你正在使用的课程贴出来吗!我似乎无法正确调用我的二传手,尝试调用它时我得到一个BAD_ACCESS
。我想知道我是否正确地声明了我的类,它是UIButton
的子类,并且我符合UIAppearanceContainer
就像它在文档中所说的那样!干杯!
@Rich Checkout 我的gist,包括全班,希望对您有所帮助。
不幸的是,这不允许我更改特定实例的颜色。知道如何实现吗?谢谢!
遗憾的是,对此的回应很晚,但我发现将方法标记为动态解决了 UIButton 的 BAD_ACCESS 问题。以上是关于Swift 中的外观代理/UI_APPEARANCE_SELECTOR?的主要内容,如果未能解决你的问题,请参考以下文章