外观代理和图层
Posted
技术标签:
【中文标题】外观代理和图层【英文标题】:Appearance Proxies & Layers 【发布时间】:2012-01-08 15:24:36 【问题描述】:是否可以使用 ios 5 外观代理来重构在图层上设置属性的代码?
_button.layer.cornerRadius = 5.0f;
_button.layer.borderWidth = 1.0f;
_button.layer.borderColor = [[UIColor blackColor] CGColor];
_button.layer.masksToBounds = YES;
【问题讨论】:
我觉得目前错误的答案被标记为正确:-) Tieme's answer 专门针对香草 UIButton 是正确的。但是,如果您乐于以Sandy's answer 中所示的简单方式扩展 UIButton,则可以实现您在问题中要求的效果。 【参考方案1】:接受的答案不正确。您可以在图层上设置属性,但是,您需要将视图子类化并通过访问器公开图层属性。
为了说明,我将只使用问题中的一个属性,cornerRadius
:
第 1 步: 实现一个 UIButton 子类。
#import <UIKit/UIKit.h>
@interface MyRoundedCornerButton : UIButton
@end
第 2 步:
添加标记为UI_APPEARANCE_SELECTOR
的属性。
#import <UIKit/UIKit.h>
@interface MyRoundedCornerButton : UIButton
@property (readwrite, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
@end
第 3 步: 实现新类。
@implementation MyRoundedCornerButton
- (void)setCornerRadius:(CGFloat)cornerRadius
self.layer.cornerRadius = cornerRadius;
@end
第 4 步: 在外观代理中设置圆角半径。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
...
[MyRoundedCornerButton appearance].cornerRadius = 10.0;
...
第 5 步: 然后在 IB 中(或您定义创建视图的任何地方),将自定义视图类设置为(或实例化)MyRoundedCornerButton 而不是 UIButton。
注意事项:
我这样做是为了在我的应用程序中应用一个易于更改的渐变背景。就我而言,所有视图控制器的根视图都使用自定义类。这个自定义类通过+(Class)layerClass
方法提供了一个CAGradientLayer
。然后,我使用UI_APPEARANCE_SELECTOR
标签公开底层渐变层的colors
和locations
属性。在应用程序初始化时设置一次可以自定义整个应用程序。您甚至可以向用户公开颜色,以允许他们完全自定义各种控件的颜色。
【讨论】:
谢谢!不应该是MyRoundedCornerButton : UIButton
吗?
另一个不相关的建议 - 如果您使用 NSNumber
作为圆角半径的类型,您还可以使用 User Defined Runtime Attributes
覆盖 IB 的外观默认值。
@Benjohn,你是对的,它应该是 UIButton(我会更新我的答案)。使用User Defined Runtime Attributes
设置这些值有一些注意事项(例如,当您有多个相互影响的 UI_APPEARANCE_SELECTOR 成员时),但在大多数情况下,您不会遇到这些问题。此外,适用于此的新内容是,如果您使用 Swift,则不再需要 UI_APPEARANCE_SELECTOR
注释,您可以使用 @IBInspectable
向您的成员公开值,以便在 IB 中更轻松地编辑它们。
我想知道是否可以将这些 UI_APPEARANCE_SELECTOR 方法添加到一个类别中,以便为所有 UIView 实例提供它们。我猜“不!”,但是,嘿,如果可以的话,它会是净值,对吧?!
@Benjohn,实际上您可以将它们添加到类别中。我已经为 UIView 添加了可在我的应用程序中的任何 UIView 上设置的borderWidth 和borderColor 属性。【参考方案2】:
不.. Apple 说:
要支持外观定制,类必须符合 UIAppearanceContainer 协议和相关的访问器方法必须是 标有 UI_APPEARANCE_SELECTOR。
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAppearance_Protocol/Reference/Reference.html
而 UIButton 没有。
编辑: 并且 UIButton 没有任何标有 UI_APPEARANCE_SELECTOR 的方法。
【讨论】:
UIButton 实际上支持外观代理,事实上你可以看到在 2011 年 WWDC 提供的“自定义 UIKit 控件的外观”会话中 Apple 提供的演示中使用了 UIButton。链接developer.apple.com/videos/wwdc/2011 (看大约 28 分钟) OP 不是询问控件视图的 CALayer,而不是专门询问 UIButton 吗?以上是关于外观代理和图层的主要内容,如果未能解决你的问题,请参考以下文章