UIAppearance not taking effect on UILabels created programmatically

前端 未结 5 1946
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-07 07:34

We have extended UILabel to be able to apply standard fonts and colors for all uses of a given label type in our apps. Eg.

@interface UILabelHeadingBold : UILab         


        
相关标签:
5条回答
  • 2021-02-07 08:16

    @robert.wijas solution works great !

    For iOS 7 and upwards I had to update the key since the one he used are deprecated for 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);
        }
    }
    
    0 讨论(0)
  • 2021-02-07 08:25

    A workaround that I've used is to manually apply the color from the appearance that is set:

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

    This way you don't need to reference anything new, or explicitly define the color. This also works for context specific coloring:

    label.textColor = UILabel.appearance(whenContainedInInstancesOf:[MyView.self]).textColor
    
    0 讨论(0)
  • 2021-02-07 08:26

    From Apple documentation :

    To support appearance customization, a class must conform to the UIAppearanceContainer protocol and relevant accessor methods must be marked with UI_APPEARANCE_SELECTOR.

    For example in UINavigationBar.h, tintColor is marked with UI_APPEARANCE_SELECTOR

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

    But in UILabel.h you can see that the textColor and font propertys are not marked with UI_APPEARANCE_SELECTOR but somehow it works when added in Interface Builder (following the documentation it shouldn't work at all).

    0 讨论(0)
  • 2021-02-07 08:34

    Simple hack that is working for me with no issues is to create a category with a UIAppearance setter that modifies UILabel properties.

    Following UIAppearance conventions I created a method:

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

    In UILabel category:

    @interface UILabel (UISS)
    
    - (void)setTextAttributes:(NSDictionary *)numberTextAttributes UI_APPEARANCE_SELECTOR;
    
    @end
    

    I'm still trying to figure out why the original setter does not work.

    0 讨论(0)
  • 2021-02-07 08:34

    I was having this exact same issue, but in Swift. A custom UILabel's appearance would work if added from a storyboard, but not if added from code.

    Here's a solution I found in Swift that's working for me:

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

    Then add these lines where you configure your app appearance:

    MyLabel.appearance().customFont = UIFont.systemFont(ofSize: 20)
    MyLabel.appearance().customColor = UIColor.magenta
    
    0 讨论(0)
提交回复
热议问题