How to use UIAppearance to style a subclass but not the superclass?

I'm styling my UINavigationBar with UIAppearance. I want all the back buttons to have gray text and all my rightBarButtonItems to have green text (colors are hypothetical). Since both buttons are UIBarButtonItems by default, UIAppearance would not be able to differentiate the two. So I decided to subclass a UIBarButtonItem, calling it ActionBarButtonItem. I use this new subclass anywhere I need a rightBarButtonItem.

rightBarButtonItem
UIBarButtonItem* done = [[ActionBarButtonItem alloc] 
    initWithTitle:@"Done"
    style:UIBarButtonItemStyleDone
    target:self 
    action:@selector(onDonePress)];
self.navigationItem.rightBarButtonItem = done;
[done release];
UIAppearance
NSDictionary* buttonStyle = [NSDictionary 
    dictionaryWithObjects:[NSArray 
        arrayWithObjects:
            [UIColor grayColor],
            , nil
        ]
        forKeys:[NSArray
            arrayWithObjects:
                UITextAttributeTextColor,
                nil
        ]
];

NSDictionary* actionStyle = [NSDictionary 
    dictionaryWithObjects:[NSArray 
        arrayWithObjects:
            [UIColor greenColor],
            nil
        ]
        forKeys:[NSArray
            arrayWithObjects:
                UITextAttributeTextColor,
                nil
        ]
]; 

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationController class], nil] 
    setTitleTextAttributes:buttonStyle
    forState:UIControlStateNormal
];

[[ActionBarButtonItem appearanceWhenContainedIn:[UINavigationController class], nil]
    setTitleTextAttributes:actionStyle
    forState:UIControlStateNormal
];

Theoretically, the gray text would be applied for all UIBarButtonItems. Then I override that gray text with green text for ActionBarButtonItems only. The final result is not as expected. For unknown reasons, every UIBarButtonItem gets green text. Why?

Answers


You are sub classing UIBarButton so my initial thought here is that when you call appearanceWhenContainedIn on ActionBarButtonItem the result is a call on the super classes appearanceWhenContainedIn and therefore this is why this is happening. It is not ideal but you could change the appearance of the left and right items on the view did load or view will appear in each view.

NSDictionary* buttonStyle = [NSDictionary 
                                 dictionaryWithObjects:[NSArray 
                                                        arrayWithObjects:
                                                        [UIColor blueColor],nil]
                                 forKeys:[NSArray
                                          arrayWithObjects:
                                          UITextAttributeTextColor,
                                          nil
                                          ]
                                 ];

NSDictionary* actionStyle = [NSDictionary 
                             dictionaryWithObjects:[NSArray 
                                                    arrayWithObjects:
                                                    [UIColor greenColor],
                                                    nil
                                                    ]
                             forKeys:[NSArray
                                      arrayWithObjects:
                                      UITextAttributeTextColor,
                                      nil
                                      ]
                             ]; 



[self.navigationItem.leftBarButtonItem setTitleTextAttributes:buttonStyle forState:UIControlStateNormal];
[self.navigationItem.rightBarButtonItem setTitleTextAttributes:actionStyle forState:UIControlStateNormal];

You may also choose to put this somewhere convent like your app delegate so you can access it more simply with [[UIApplication sharedApplication].delegate setBarButtonColors]. Another alternative could be a category on UINavigationBar.


Need Your Help

Swift proper use of UITextField

ios swift uibutton uitextfield

I have an application where is Label - Textfield. Many of users clicking on label and hope they will edit the UITextField. What is proper implementation of this problem? Should I create a button that

Why can I not call my class's constructor from an instance of that class in C++?

c++ constructor destructor

When can an object of a class call the destructor of that class, as if it's a regular function? Why can't it call the constructor of the same class, as one of its regular functions? Why does the co...