18

我们扩展了 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 中使用时才有效?

4

5 回答 5

20

从苹果文档:

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

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

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

但是在 UILabel.h 中,您可以看到textColorandfont属性没有用 UI_APPEARANCE_SELECTOR 标记,但是当在 Interface Builder 中添加时它以某种方式起作用(按照文档,它根本不应该起作用)。

于 2012-08-05T14:24:40.573 回答
14

对我来说没有问题的简单技巧是使用修改 UILabel 属性的 UIAppearance 设置器创建一个类别。

遵循 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

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

于 2012-12-22T21:25:23.383 回答
6

我遇到了同样的问题,但是在 Swift 中。如果从情节提要中添加customUILabel的外观将起作用,但如果从代码中添加则不会。

这是我在 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
于 2019-02-01T21:06:28.613 回答
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);
    }
}
于 2014-11-24T22:04:02.203 回答
0

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

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

这样你就不需要引用任何新的东西,或者明确定义颜色。这也适用于特定于上下文的着色:

label.textColor = UILabel.appearance(whenContainedInInstancesOf:[MyView.self]).textColor
于 2018-04-02T22:46:42.757 回答