How to create Multiple Themes Skins for iphone apps

0 votes
I already have an iPhone app that the app store has authorised. I now want to design many themes for my app. Can someone please give me information, links, or instructions on how to make themes for my app?

For the Boys, I want to make a Metal theme, and for the Girls, a Pink theme. Again, by theme, I mean that the features and functionality of the entire app will remain the same, but the user can select the theme they want to view based on whether they are a boy or a girl. Additionally, just the graphics, backgrounds, and music will alter when the theme is changed to reflect the applied theme.

A big thank you!
Sep 28, 2022 in IOS by Soham
• 9,710 points
839 views

No answer to this question. Be the first to respond.

Your answer

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
0 votes

First, decide which areas of the app you want to skin and when you want to provide users with the option to switch skins.

I'm going to assume that you want to alter the colours of the text and the graphics and that it's acceptable for the user to have to restart the app in order to change the skin (that will make things simpler for now).

Make a plist with all of your skinnable graphics and colours. The plist will be a dictionary with appropriate, theme-neutral key names for the images and colours (for example, call red "primaryHeadingColor" instead of "red"). Colours may be represented by hex strings and images by file names.

+ (ThemeManager *)sharedManager
{
    static ThemeManager *sharedManager = nil;
    if (sharedManager == nil)
    {
        sharedManager = [[ThemeManager alloc] init];
    }
    return sharedManager;
}

The ThemeManager class will have an NSDictionary property called "styles", and in the init method you will load the theme into your styles dictionary like this:

- (id)init
{
    if ((self = [super init]))
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSString *themeName = [defaults objectForKey:@"theme"] ?: @"default";

        NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:@"plist"];
        self.styles = [NSDictionary dictionaryWithContentsOfFile:path];
    }
    return self;
}

Since applications lack a css stylesheet counterpart, this is rather challenging.

(Note: Some individuals dislike exerting a lot of effort within an init approach. Although I've never experienced a problem with it, if you like, you can construct a separate method to load the themes dictionary and call it from the setup code of your programme.

Observe how I'm using user defaults to retrieve the name for the theme plist. So, if a user chooses a theme in their preferences, saves it, and then launches the app later, it will use that theme. If no theme is chosen, I've included a default theme with the name "default," so make sure you have a default.plist theme file (or alter the @"default" in the 

code to whatever the real name of your default theme plist is).

You need to use your theme now that it has been loaded; presuming your app contains a variety of images and text labels. This phase is simple if you're loading and laying those out in code. It's a little difficult if you're doing it in nibs, but I'll describe how to manage that later.

Normally, you would say: "Loading" to load an image.

UIImage *image = [UIImage imageNamed:@"myImage.png"];

But if you want that image to be themable, you'll now need to load it by saying

NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *imageName = [styles objectForKey:@"myImageKey"];
UIImage *image = [UIImage imageNamed:imageName];

This will load the themed picture that matches the key "myImageKey" in your theme file. Your style will change depending on whatever theme file you've loaded.

You might wish to include those three lines in a function because you'll use them frequently. It would be a fantastic idea to add a category to UIImage that designates a method with a name like:

+ (UIImage *)themeImageNamed:(NSString *)key;

You can then use it by simply substituting any calls to [UIImage imageNamed:@"foo.png"] with [UIImage themeImageNamed:@"foo"], where foo now refers to the theme key rather than the actual image name.

The process of theming your photographs is now complete. Pretend you're now establishing your label colours by saying: Let's say you want to theme your label colours.

someLabel.color = [UIColor redColor];

You would now replace that with:

NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *labelColor = [styles objectForKey:@"myLabelColor"];
someLabel.color = [UIColor colorWithHexString:labelColor];

You've probably noticed that UIColor lacks the method "colorWithHexString:"; you'll need to add it by creating a category. To get code to do that, search "UIColor with hex string" solutions on Google, or check out this useful category I created: https://github.com/nicklockwood/ColorUtils

If you've been paying attention, you may also be considering adding a method to UIColor with the following name rather than repeatedly writing those three lines:

+ (UIColor *)themeColorNamed:(NSString *)key;

Similar to how we handled UIImage? Great concept!

That's it, then. Any image or label in your app can now be themed. The font name and a variety of other potentially customizable aesthetic features might both be set using the same approach.

We've forgotten one little thing, though.

These strategies won't work if you've created the majority of your views as nibs (and I don't see why you wouldn't), as your image names and font colours are hidden inside impenetrable nib data and aren't being set in your source code.

There are several methods to resolve this:

1) You could duplicate your nibs and theme them, then load the nib names into your theme plist. That's not too bad, just implement the nibName method of your view controllers like this:

- (NSString *)nibName
{
    NSDictionary *styles = [ThemeManager sharedManager].styles;
    return [styles objectForKey:NSStringFromClass([self class])];
}

Because you can create a base ThemeViewController with that method and have all your themable view controllers inherit from it, you can save yourself some typing by noticing my clever approach of utilising the class name of the view controller as the key.

However, if you need to alter any screens later, this method requires storing several copies of each nib, which is a maintenance nightmare.

2) You could create IBOutlets for each of your imageViews and labels, then set the colours and pictures for each of them in your viewDidLoad function. The process is arguably the most time-consuming, but at least you won't need to keep multiple nibs (this is effectively the same issue as localising nibs, by the way, and is very similar). 

3) You could create a unique subclass of UILabel called ThemeLabel that, when the label is instantiated, uses the code above to automatically set the font colour. You could then use these ThemeLabels in your nib files in place of standard UILabels by setting the label's class in Interface Builder to ThemeLabel. Unfortunately, you will need to develop a distinct UILabel subclass for each style if you have more than one font or font colour.

Alternatively, you could be crafty and utilise the accessibilityLabel attribute or the view tag as the style dictionary key, allowing you to use a single ThemeLabel class and the accessibility label setting in Interface Builder to choose the style.

Create a subclass of UIImageView for ImageViews called ThemeImageView that, in the awakeFromNib method replaces the image with a theme image based on the tag or accessibilityLabel property. to use the same trick.

The fact that option 3 reduces coding is why I personally prefer it. The ability to switch themes at runtime is another benefit of option 3, since you may create a system where your theme manager reloads the theme dictionary before broadcasting an NSNotification instructing all ThemeLabels and ThemeImageViews to redraw. It would most likely only require an additional 15 lines of code.

You now have a full-featured solution for theming iOS apps. Thank you very much!

answered Sep 28, 2022 by Rahul
• 9,680 points

edited Mar 5

Related Questions In IOS

0 votes
1 answer

Is it possible to run .APK/Android apps on iPad/iPhone devices?

It is not possible to run Android ...READ MORE

answered Sep 20, 2022 in IOS by Aditya
• 7,680 points
4,860 views
0 votes
0 answers

How to connect iphone to a local server running on mac?

I am running a django server at ...READ MORE

Sep 22, 2022 in IOS by Soham
• 9,710 points
827 views
0 votes
1 answer

"Scan now to download" QR code for iPhone App Download

They are QR Codes, which can link ...READ MORE

answered Nov 8, 2022 in IOS by Rahul
• 9,680 points
1,036 views
0 votes
1 answer

How to get rid of blank space from iPhone notch on web page

You should be looking for the meta-setting ...READ MORE

answered Nov 8, 2022 in IOS by Rahul
• 9,680 points
2,275 views
0 votes
0 answers

How to access and read a file on a USB drive from IOS? (Connected via OTG cable to iPhone)

Can I access a text file on ...READ MORE

Nov 7, 2022 in IOS by Soham
• 9,710 points
675 views
0 votes
1 answer

How do i open Google Maps for directions using coordinates on the iphone

There is a chance. Employ MKMapView Using ...READ MORE

answered Nov 8, 2022 in IOS by Rahul
• 9,680 points
677 views
0 votes
0 answers

In custom iOS keyboard detect the app

How to detect in which app my ...READ MORE

Nov 17, 2022 in Mobile Development by gaurav
• 23,260 points
427 views
0 votes
1 answer

Getting country calling prefix

For a class that offers both this ...READ MORE

answered Sep 20, 2022 in Others by Aditya
• 7,680 points
963 views
0 votes
1 answer

white screen on simulator iphone Xcode

After creating the request, you must actually ...READ MORE

answered Sep 20, 2022 in Others by Aditya
• 7,680 points
4,148 views
0 votes
1 answer

Is there a way to to check if a picture was taken on that iPhone?

Actually, the model and manufacturer information is ...READ MORE

answered Sep 22, 2022 in IOS by Rahul
• 9,680 points
781 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP