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.
source to share
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.
source to share
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.
source to share