I am new to iOS development and was wondering how to add a night theme similar to tweetbot 3 and clear. From my research I haven't really been able to find anything on theming iOS apps.
Would I remake the app in another storyboard specific for the theme?
thanks.
To add to what others have said, there is a WWDC video on theming your code. I've taken that a step further and created a lightweight framework for theming that I use in a couple of my apps. The gist is as follows.
Each time you create a label, button, etc (or when they are going to appear on the screen, if you use interface builder), you pass them to a Theme instance that sets their look and feel. If several UI components work together, use the Facade design pattern to combine them into a single object (so, for example, if you have a button that has a customer wrapper, a label, and an image in a particular place, wrap them into a single class called - for example's sake - WrappedButton).
I sometimes find it easier to communicate in uml, so...
The Theme Protocol could look something like this.
@protocol Theme <NSObject>
- (void)themeHeadingLabel:(UILabel *)headingLabel;
- (void)themeBodyLabel:(UILabel *)bodyLabel;
- (void)themeNavigationButton:(UIButton *)navigationButton;
- (void)themeActionButton:(UIButton *)actionButton;
@end
Incidentally, I usually put the code in there to allow the buttons, labels, etc, to respond to text size changes (from the Settings app) in iOS7. So there could also be methods like,
- (void)respondToTextSizeChangeForHeadingLabel:(UILabel *)headingLabel;
- (void)respondToTextSizeChangeForBodyLabel:(UILabel *)bodyLabel;
// and do the same for buttons
Then, of course, you'll have one or more implementations of that protocol. This is where your themes will live. Here are a few snippets of what that may look like.
#import "Theme.h"
@interface LightTheme : NSObject <Theme>
@end
@implementation LightTheme
- (void)themeHeadingLabel:(UILabel *)headingLabel
{
headingLabel.backgroundColor = [UIColor lightTextColor];
headingLabel.textColor = [UIColor darkTextColor];
headingLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
}
// the rest of your theming
@end
And you could have a dark theme whose implementation looks something like this.
@implementation DarkTheme
- (void)themeHeadingLabel:(UILabel *)headingLabel
{
headingLabel.backgroundColor = [UIColor darkGrayColor];
headingLabel.textColor = [UIColor lightTextColor];
headingLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
}
// the rest of your theming
@end
I always wrap that in a ThemeManager to help me keep track of the theme. That can look something like this.
#import "Theme.h"
@interface ThemeManager : NSObject
+ (id <Theme>)theme;
@end
#import "LightTheme.h"
#import "DarkTheme.h"
@implementation ThemeManager
+ (id <Theme>)theme
{
// here you'd return either your light or dark theme, depending on your program's logic
}
@end
Now, to tie it all together you can either use it directly or in a factory.
UILabel* headingLabel = [[UILabel alloc] init];
headingLabel.text = @"My Heading";
[[ThemeManager theme] themeHeadingLabel:myHeading];
// use the label
Or as a factory, the implementation would look something like this.
- (UILabel *)buildLabelWith:(NSString *)text
{
UILabel* headingLabel = [[UILabel alloc] init];
headingLabel.text = text;
[[ThemeManager theme] themeHeadingLabel:myHeading];
return headingLabel;
}
Hope that helps. If you have any questions, let me know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With