Switching between two color schemes for an app?

For example, I want light colors for all my views (background and labels) during the day and dark colors at night. The app will automatically change its color over time. Also, the user can switch to a different color scheme in the settings. What's the most efficient way to do this?

Several colors (background and labels) are involved in the switch.

+3


source to share


2 answers


I have done something very similar in the recent past; the application requires a variety of user-selectable color schemes.

Topic

Create a theme class with properties for each of your color types. Try to avoid describing the specific use of ( submitButtonBackgroundColor

), instead describe the purpose (this way you will end up with far fewer color definitions):

extern NSString * const ThemeChanged;

@interface Theme : NSObject

+ (Theme *)currentTheme;
+ (void)setCurrentTheme:(Theme *)theme;

@property (nonatomic, strong) UIColor *backgroundColor;
@property (nonatomic, strong) UIColor *foregroundColor;
@property (nonatomic, strong) UIColor *darkerForegroundColor;
@property (nonatomic, strong) UIColor *lighterForegroundColor;
@property (nonatomic, strong) UIColor *highlightColor;

@end

      

Implementation:

NSString * const ThemeChanged = @"ThemeChanged";

static Theme *_currentTheme = nil;

// Note this is not thread safe

@implementation Theme

+ (Theme *)currentTheme {
    return _currentTheme;
}

+ (void)setCurrentTheme:(Theme *)theme {
    _currentTheme = theme;

    [[NSNotificationCenter defaultCenter] postNotificationName:ThemeChanged object:nil];
}

@end

      



This class can then be created with each of your desired schemes (one for the day, one for the night).

Each of your view controllers must access to [Theme currentTheme]

receive colors. They (your view controllers) can also register themselves as a notification watcher ThemeChanged

to dynamically update their view colors if theme changes with setCurrentTheme:

.

Day / Night Definition

As for the automatic update based on the time of day, you can use a recurring one NSTimer

at a reasonable interval, check the current time and call setCurrentTheme:

that dark theme object that you created.

@interface DayNightHandler : NSObject
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation DayNightHandler

- (instancetype)init
{
    self = [super init];
    if (self) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                  target:self
                                                selector:@selector(checkTime)
                                                userInfo:nil
                                                 repeats:YES];
    }
    return self;
}

- (void)checkTime {
    NSDate *currentDate = [NSDate date];
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitHour | NSCalendarUnitMinute
                                                                   fromDate:currentDate];

    NSLog(@"%@",components);

    // Very crude
    if (components.hour >= 18 || components.hour <= 6) {
        // set dark theme
    } else {
        // set light theme
    }
}

@end

      

You might want to trade the day / night check for something more solid, this is just a high level example to help you on the right track.

+5


source


Create one property named appColor

type UIColor

in the AppDelegate.h file. Create your custom getter and add your logic for synchronization as well as selection from settings.

Just set the color using



self.view.backgroundColor = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).appColor

      

this will execute your custom getter and return the color as per your logic.

-3


source







All Articles