Reputation: 1649
For instance, I want light colors for all my views(background and labels) during the day and dark colors at night. The app will change its color automatically according to the time. Also the user will be able to switch to the other color scheme in settings. What is the most efficient way of doing this?
Multiple colors are involved in the switch (background and labels).
Upvotes: 3
Views: 845
Reputation: 9002
I have done something very similar in the recent past; an app required various, user-selectable, colour schemes.
Create a Theme class with properties for each of your colour types. Try to stay away from describing the specific usage (submitButtonBackgroundColor
), instead describe the purpose (this way you'll end up with much fewer colour 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 instantiated with each of your desired schemes (one for day, one for night).
Each of your view controllers will need to access [Theme currentTheme]
to retrieve the colours. They (your view controllers) can also register as an observer of the ThemeChanged
notification in order to dynamically update their view's colours if/when you change the theme using setCurrentTheme:
.
As for updating automatically based on the time of day you could use a repeating NSTimer
with a reasonable interval, check the current time and call setCurrentTheme:
with the dark theme object 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 may want to swap out the crude day/night check for something a bit more solid, this is purely a high-level example intended to get you on the right track.
Upvotes: 6
Reputation: 4941
Create one property named appColor
of type UIColor
in AppDelegate.h File.
Create its custom getter, and add your logic for timing as well as selection from settings.
Just set color by using,
self.view.backgroundColor = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).appColor
this will execute your custom getter method and return color as per your logic.
Upvotes: -3