我啥时候可以开始使用使用 UIAppearance 设置的属性?

Posted

技术标签:

【中文标题】我啥时候可以开始使用使用 UIAppearance 设置的属性?【英文标题】:When can I start using properties set using UIAppearance?我什么时候可以开始使用使用 UIAppearance 设置的属性? 【发布时间】:2012-05-24 12:21:36 【问题描述】:

我的视图类中有一些自定义外观属性(UIView 的后代)。我想根据这些属性自定义视图外观,但我不能在初始化程序中这样做,因为使用 [[MyClass appearance] setFoo:…] 设置的值此时无效:

@interface View : UIView
@property(strong) UIColor *someColor UI_APPEARANCE_SELECTOR;
@end

@implementation View
@synthesize someColor;

// Somewhere in other code before the initializer is called:
// [[View appearance] setSomeColor:[UIColor blackColor]];

- (id) initWithFrame: (CGRect) frame

    self = [super initWithFrame:frame];
    NSLog(@"%@", someColor); // nil
    return self;


@end

它们已在layoutSubviews 中设置,但这不是执行视图自定义的好点,因为某些自定义可能会再次触发layoutSubviews,从而导致无限循环。

那么,执行自定义有什么好处呢?或者有没有办法触发应用外观值的代码?

【问题讨论】:

我认为一旦自定义类被分配,成员的属性总是可以根据需要访问和更改,然后对象可以与代码中的修改信息一起使用。 只是为了确保,我说的是通过外观代理 (UIAppearance) 设置的属性。这些值设置在初始化程序之后的某个位置。如果我在属性设置器上设置断点,我可以看到这些值是从 [CALayer layoutSublayers] 应用的。 【参考方案1】:

一种可能的解决方法是直接从代理中获取值:

- (id) initWithFrame: (CGRect) frame

    self = [super initWithFrame:frame];
    NSLog(@"%@", [[View appearance] someColor); // not nil
    return self;

当然,这会取消根据视图容器改变外观的选项,并且通常很难看。我发现的第二个选项是在 setter 中执行自定义:

- (void) setSomeColor: (UIColor*) newColor

    someColor = newColor;
    // do whatever is needed

我还是希望有一些在外观属性设置后被调用的钩子。

【讨论】:

看我的回答; “钩子”是 UIView didMoveToSuperview:,我相信。【参考方案2】:

为什么不等到

- (void)willMoveToSuperview:(UIView *)newSuperview 
    [super willMoveToSuperview:newSuperview];

    if (newSuperview) 
        ... code here ...
    

如果它给你带来麻烦?

【讨论】:

这是我的下一次尝试,但当时也没有设置值。【参考方案3】:

我相信UIAppearance 属性会在视图添加到视图层次结构时应用于视图。所以大概你可以访问UIView didMoveToSuperview中的设置属性。

【讨论】:

【参考方案4】:

警告:我使用的是 Swift 2,所以不确定 Swift / Objective-C 的早期版本。但我发现didMoveToSuperview() 不起作用。这些属性在layoutSubviews() 中可用,但这不是做这种事情的好地方(因为它可以被多次调用)。在我发现的视图生命周期中访问这些属性的最佳位置是didMoveToWindow()

【讨论】:

【参考方案5】:

如果是一次性的,我会认为 viewDidLoad 是最好的。否则,viewWillAppear。

编辑:

如果您想在视图中执行此操作,而不是控制器,那么我将按照以下方式为视图创建自定义初始化:

-(id) initWithFrame:(CGRect) frame andAppearanceColor:(UIColor)theColor;

从而在创建时将颜色传递到视图中。

【讨论】:

这些是控制器方法,我更愿意在视图中处理它。此外,很可能在这些调用期间尚未设置值。 在初始化程序中传递颜色也不是一种选择,因为要设置更多外观属性,并且初始化程序在控制器的... erm, control之外的地方调用>。可以说外观代理 API 的全部意义在于摆脱一直手动设置值。 我知道你来自哪里。也许您可以创建一个方法来设置外观属性并调用它以响应 NSNotification(在指定外观属性时发送)? 在通过[[View appearance] setSomeColor:…]设置外观属性的时候,View的实例还不存在,所以很遗憾也没有这个选项。

以上是关于我啥时候可以开始使用使用 UIAppearance 设置的属性?的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候开始看到付款? [关闭]

我啥时候应该使用装饰器?

MySQL存储过程与函数,我啥时候使用?

MySQL存储过程与函数,我啥时候使用?

MySQL存储过程与函数,我啥时候使用?

我啥时候应该使用一对一的关系?