views:

96

answers:

2

Hi I am trying to write some iPhone app with a theme switcher, where users can select a theme to change the background color, alpha, images, and some push buttons' look and feel as well (size, image, or even locations).

What would be the best way to apply the theme?

Thanks, Tim

A: 

Haven't got any answers. I implemented it with events and singlton. Basically a singleton setting object dispatches changes to observers, which update the GUI upon the events. I remember there is a way you can listen to an instance variable change, but forgot how. My current way works pretty well for me anyway.

Tim
+1  A: 

Here's how I implemented the ability to change themes in FemCal. I've included some of the details in the form of code snippets.

  1. Create a singleton ThemeMgr class that stores colors, images etc. Fetch the singleton when needed.

    @interface ThemeMgr : NSObject 
    {
    // selected color and image
    NSString * selectedColor;
    NSString * selectedPicture;
    // dictionaries for color and image
    NSDictionary * colorData;
    NSDictionary * imageData;
    NSDictionary * backgroundData;
    // names
    NSArray * colors;
    NSArray * images;
    // themes
    UIColor * tintColor;
    UIImageView * panelTheme;
    UIColor * tableBackground;
    }

  2. Use notifications to broadcast theme changes. I used @"ThemeChange" as the notification.

    - (void)fireTimer:(NSTimer *)timer
    {
    NSNotification * themeChange = [NSNotification notificationWithName:@"ThemeChange" object:nil];
    [[NSNotificationQueue defaultQueue] enqueueNotification:themeChange postingStyle:NSPostWhenIdle];
    }
    Obviously, you'll have some UI to select a desired theme. In this case, the user chooses a theme and fireTimer is fired after 0.5 seconds. This gives a nice delay for other UI to update before I force the UI to redraw itself.

  3. Listen for notifications anywhere you need to act on a theme change.

    // listen for change notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateAppearance:) name:@"ThemeChange" object:nil];
    I only have a few views, so I've written the code in each controller I use, but you can use the power of objective-C to mix code in to handle this in a better way.

  4. Implement the code to actually redraw your view based on the theme.

    - (void)updateAppearance:(NSNotification *)notification
    {
    // background for grouped table view
    ThemeMgr * themeMgr = [ThemeMgr defaultMgr];
    // change color and reload
    [self.tableView setBackgroundColor:[themeMgr tableBackground]];
    [self.tableView reloadData];
    self.navigationController.navigationBar.tintColor = [themeMgr tintColor];
    }
    

Don't forget to resign any notifications when necessary, and you'll have to write code in viewDidLoad or similar to apply any themes before the view is displayed.

Jonathan Watmough