【问题标题】: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,则可以实现您在问题中要求的效果。

标签: ios ios5 uikit


【解决方案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 标签公开底层渐变层的colorslocations 属性。在应用程序初始化时设置一次可以自定义整个应用程序。您甚至可以向用户公开颜色,以允许他们完全自定义各种控件的颜色。

【讨论】:

  • 谢谢!不应该是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 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 2019-07-25
相关资源
最近更新 更多