Daniel Daniel - 3 months ago 28
iOS Question

Change UITabBar style with a switch

I'm trying to make a dark mode switch. I started with this tutorial (link), but I can't change the tabBar's style. The navBar's style changes, but the tabBar stays the same.

How can I change the tabBar's appearance without restarting the app?

Update #1: here's the code that I use

import UIKit

enum Theme: Int {
case Light, Dark

var barStyle: UIBarStyle {
switch self {
case .Light:
return .Default
case .Dark:
return .Black
}
}

var backgroundColor: UIColor {
switch self {
case .Light:
return UIColor(red:0.95, green:0.95, blue:0.95, alpha:1.00)
case .Dark:
return UIColor(red:0.12, green:0.12, blue:0.12, alpha:1.00)
}
}

var cellBackgroundColor: UIColor {
switch self {
case .Light:
return UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.00)
case .Dark:
return UIColor(red:0.15, green:0.15, blue:0.15, alpha:1.00)
}
}

var labelColor: UIColor {
switch self {
case .Light:
return UIColor(red:0.12, green:0.12, blue:0.12, alpha:1.00)
case .Dark:
return UIColor(red:0.99, green:0.99, blue:0.99, alpha:1.00)
}
}

var buttonColor: UIColor {
switch self {
case .Light:
return UIColor(red:0.22, green:0.59, blue:0.95, alpha:1.00)
case .Dark:
return UIColor(red:0.22, green:0.59, blue:0.95, alpha:1.00)
}
}

var separatorColor: UIColor {
switch self {
case .Light:
return UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.00)
case .Dark:
return UIColor(red:0.22, green:0.22, blue:0.22, alpha:1.00)
}
}

var tintColor: UIColor {
switch self {
case .Light:
return UIColor(red:0.62, green:0.62, blue:0.62, alpha:1.00)
case .Dark:
return UIColor(red:0.50, green:0.50, blue:0.50, alpha:1.00)
}
}
}

class ThemeManager {
static func currentTheme() -> Theme {
if(NSUserDefaults.standardUserDefaults().boolForKey("darkMode")){
return .Dark
} else {
return .Light
}
}

static func applyTheme(theme: Theme) {
if(theme == .Dark){
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "darkMode")
} else {
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "darkMode")
}
NSUserDefaults.standardUserDefaults().synchronize()

let sharedApplication = UIApplication.sharedApplication()
sharedApplication.delegate?.window??.tintColor = theme.buttonColor

UINavigationBar.appearance().barStyle = theme.barStyle
UITabBar.appearance().barStyle = theme.barStyle
UITabBar.appearance().barTintColor = theme.labelColor

UINavigationBar.appearance().tintColor = theme.labelColor

UITableViewCell.appearance().backgroundColor = theme.cellBackgroundColor

UIStepper.appearance().tintColor = theme.tintColor
UIActivityIndicatorView.appearance().tintColor = theme.tintColor

UIButton.appearance().tintColor = theme.buttonColor
UILabel.appearance().textColor = theme.labelColor
}
}


I call
ThemeManager.applyTheme(.Dark || .Light)
when the switch's status changes.

Answer

UIAppearance proxy only affects new initialised views. Setting colours and styles on UIAppearance won't have effect on views that are already visible.

You have to set it manually in ViewController:

self.tabBarController?.tabBar.barStyle = .Black