10

我的视图类(的后代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再次触发,从而导致无限循环。

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

4

5 回答 5

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
}

我仍然希望在设置外观属性后调用一些钩子。

于 2012-05-24T14:33:48.463 回答
1

为什么不等到

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

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

如果它给你带来麻烦?

于 2012-05-24T12:46:21.940 回答
1

我相信UIAppearance在将视图添加到视图层次结构中时,属性会应用于视图。所以大概你可以在UIView didMoveToSuperview.

于 2013-08-07T19:27:22.103 回答
1

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

于 2015-12-17T16:33:10.960 回答
0

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

编辑:

如果您想在视图中而不是控制器中执行此操作,那么我将为视图创建一个自定义初始化,如下所示:

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

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

于 2012-05-24T13:23:55.710 回答