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

时间:2012-05-24 12:21:37

标签: ios cocoa-touch uiappearance

我的视图类中有一些自定义外观属性(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,从而导致无限循环。

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

5 个答案:

答案 0 :(得分:2)

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

- (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
}

我宁愿在设置外观属性后调用一些钩子。

答案 1 :(得分:1)

为什么不等到

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

    if (newSuperview) {
        ... code here ...
    }
}

如果它给你带来麻烦?

答案 2 :(得分:1)

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

答案 3 :(得分:0)

如果它是一次性的话,我会认为viewDidLoad会是最好的。否则,请查看ViewAillar。

编辑:

如果你想在视图中执行它,而不是它的控制器,那么我将为视图创建一个自定义初始化:

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

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

答案 4 :(得分:0)

我认为UIAppearance属性在添加到视图层次结构中时会应用于视图。因此,您可以访问UIView didMoveToSuperview中的设置属性。