Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a night theme for my app [closed]

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.

like image 930
user3173553 Avatar asked Dec 04 '22 08:12

user3173553


1 Answers

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

Theme UML Diagram

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.

like image 165
Travis Avatar answered Dec 18 '22 00:12

Travis