UIAppearance对以编程方式创建的UILabels没有生效

时间:2012-07-03 09:50:05

标签: ios appearance uiappearance

我们扩展了UILabel,以便能够在我们的应用中为给定标签类型的所有用途应用标准字体和颜色。例如。

@interface UILabelHeadingBold : UILabel
@end

在我们的AppDelegate中,我们应用这样的字体和颜色

[[UILabelHeadingBold appearance] setTextColor:<some color>];
[[UILabelHeadingBold appearance] setFont:<some font>];

在我们的XIB中添加UILabel时,我们现在可以选择类型为UILabelHeadingBold的类,它可以按预期工作。标签显示正确的字体和颜色,如我们的AppDelegate中所指定。

但是,如果我们以编程方式创建标签,例如

UILabelHeadingBold *headingLabel = [[UILabelHeadingBold alloc] initWithFrame:CGRectMake(10, 10, 100, 30)];
[self.mainView addSubview:headingLabel];

UILabel未获得预期的字体/颜色。我们必须手动应用这些属性。

有没有办法让UIAppearance在编程创建的UI元素上生效,还是只在XIB中使用时才有效?

5 个答案:

答案 0 :(得分:18)

来自Apple文档:

  

为了支持外观定制,一个类必须符合   UIAppearanceContainer协议和相关的访问方法必须是   用UI_APPEARANCE_SELECTOR标记。

例如,在UINavigationBar.h中,tintColor标有UI_APPEARANCE_SELECTOR

@property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;

但是在UILabel.h中你可以看到textColorfont属性没有用UI_APPEARANCE_SELECTOR标记,但是当它在Interface Builder中添加时它会起作用(遵循文档它根本不起作用) )。

答案 1 :(得分:14)

对我来说没有问题的简单黑客就是创建一个带有修改UILabel属性的UIAppearance setter的类别。

遵循UIAppearance惯例我创建了一个方法:

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes;
{
    UIFont *font = [numberTextAttributes objectForKey:UITextAttributeFont];
    if (font) {
        self.font = font;
    }
    UIColor *textColor = [numberTextAttributes objectForKey:UITextAttributeTextColor];
    if (textColor) {
        self.textColor = textColor;
    }
    UIColor *textShadowColor = [numberTextAttributes objectForKey:UITextAttributeTextShadowColor];
    if (textShadowColor) {
        self.shadowColor = textShadowColor;
    }
    NSValue *shadowOffsetValue = [numberTextAttributes objectForKey:UITextAttributeTextShadowOffset];
    if (shadowOffsetValue) {
        UIOffset shadowOffset = [shadowOffsetValue UIOffsetValue];
        self.shadowOffset = CGSizeMake(shadowOffset.horizontal, shadowOffset.vertical);
    }
}

在UILabel类别中:

@interface UILabel (UISS)

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes UI_APPEARANCE_SELECTOR;

@end

我仍在试图弄清楚为什么原来的setter不起作用。

答案 2 :(得分:4)

我遇到了同样的问题,但是在Swift中。如果从情节提要中添加自定义UILabel,则外观是可行的,但是如果从代码中添加,则外观不可行。

这是我在Swift中找到的对我有用的解决方案:

class MyLabel: UILabel { }

extension UILabel {
    @objc dynamic var customFont: UIFont! {
        get { return self.font }
        set { self.font = newValue }
    }

    @objc dynamic var customColor: UIColor! {
        get { return self.textColor }
        set {  self.textColor = newValue }
    }
}

然后在配置应用外观的位置添加以下行:

MyLabel.appearance().customFont = UIFont.systemFont(ofSize: 20)
MyLabel.appearance().customColor = UIColor.magenta

答案 3 :(得分:0)

@ robert.wijas解决方案效果很棒!

对于iOS 7及更高版本,我必须更新密钥,因为他使用的密钥已弃用7+以上:

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes;
{
    UIFont *font = [numberTextAttributes objectForKey:NSFontAttributeName];
    if (font) {
        self.font = font;
    }
    UIColor *textColor = [numberTextAttributes objectForKey:NSForegroundColorAttributeName];
    if (textColor) {
        self.textColor = textColor;
    }
    UIColor *textShadowColor = [numberTextAttributes objectForKey:NSShadowAttributeName];
    if (textShadowColor) {
        self.shadowColor = textShadowColor;
    }
    NSValue *shadowOffsetValue = [numberTextAttributes objectForKey:NSShadowAttributeName];
    if (shadowOffsetValue) {
        UIOffset shadowOffset = [shadowOffsetValue UIOffsetValue];
        self.shadowOffset = CGSizeMake(shadowOffset.horizontal, shadowOffset.vertical);
    }
}

答案 4 :(得分:0)

我使用的解决方法是从设置的外观中手动应用颜色:

let label = UILabel()
label.textColor = UILabel.appearance().textColor

这样您就不需要引用任何新内容,也不需要明确定义颜色。这也适用于特定于上下文的着色:

label.textColor = UILabel.appearance(whenContainedInInstancesOf:[MyView.self]).textColor