70

How can we change the global tint color on iOS7/iOS8 by code? I want to change multiple objects that use this property, but not change each one, that's why I want to use the global tint property.

elGeekalpha
  • 1,826
  • 3
  • 13
  • 14
  • 1
    I know you specified "by code", still, I think it's important to mention there is a global tint property in the storyboard's file inspector – Flores Robles May 25 '15 at 18:54

9 Answers9

114

Simply change the UIWindow 's tintColor in your application delegate, it's automatically passed as default to all its UIView descendants.

[self.window setTintColor:[UIColor greenColor]];
David Douglas
  • 10,377
  • 2
  • 55
  • 53
Vinzzz
  • 11,746
  • 5
  • 36
  • 42
  • You're right, fairly simple just add _window.tintColor = [UIColor purpleColor]; (autosynthesize) But can I change it from other view? – elGeekalpha Sep 23 '13 at 13:51
  • It's implemented on any `UIView` , so you can set it on any view in your views hierarchy, and all its descendants will inherit same default `tintColor` (unless you specify otherwise) – Vinzzz Sep 23 '13 at 22:26
  • 1
    IMPORTANT: don't forget to test the selector for ios6 compatibility: `if([window respondsToSelector:@selector(setTintColor:)])` – Martin Jul 10 '14 at 06:19
  • 2
    This method doesn't seem to propagate to navigation toolbars though. – PapillonUK Aug 09 '14 at 14:06
  • any custom xibs are somehow not affected by both `UIWindow`'s `tintColor` property or the Global tint as suggested in another option. Setting the `UIView`'s appearance proxy for `tintColor` works. – atastrophic Sep 29 '15 at 22:09
  • 1
    You should use appearance protocol instead, as @carmen_munich explained here: http://stackoverflow.com/a/19140595/514181 – Darrarski Jan 14 '16 at 14:40
69

[[UIView appearance] setTintColor:[UIColor greenColor]];

Carmen
  • 6,177
  • 1
  • 35
  • 40
  • 3
    If you need to tint UIAlertView buttons and not just the main app window this is that best answer! – d60402 Aug 27 '14 at 16:02
  • 4
    `UIView`'s `tintColor` doesn't have the `UI_APPEARANCE_SELECTOR` annotation. This answer is wrong. – Piotr Tobolski Oct 31 '14 at 19:26
  • 2
    I think this should be the correct answer as it affect UIAlertView while the accepted answer is not. – Joshua May 06 '15 at 14:09
  • 2
    @Tobol is technically correct. There is confusion around this and it really needs clarification from Apple. `UIAppearance` was introduced in iOS 5 as a way to handle global color (and more), but then in iOS 7 Apple moved `tintColor` to `UIView` and made it propagate to subviews. In the [iOS 7 UI Transition Guide](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html) Apple states: "Setting the tintColor property by using the appearance proxy APIs is not supported in iOS 7." Yet it still seems to work. – Jamie McDaniel Sep 14 '15 at 13:34
  • Thank you Jamie. I think we should qualify this as an undefined behavior because it can change in future iOS releases without warning. – Piotr Tobolski Sep 14 '15 at 15:34
  • @Tobol nevertheless UIView conforms to UIAppearance and UIAppearanceContainer. For example the UIBarButtonItem tintColor has no UI_APPEARANCE_SELECTOR annotation as well – Carmen Jun 20 '16 at 10:55
  • Alright, alert views are presented in their own window, separate from the app's (IIRC). – Nicolas Miari Oct 06 '16 at 10:03
  • Important! This will affect buttons disabled color and other controls state color. – Roman B. Mar 05 '17 at 21:03
  • This breaks with certain `UIBarButtonItem`s, such as the "Done" item. Use with caution. – saagarjha Mar 28 '17 at 23:41
39

There are two ways to change your global tint color. As many mentioned above you could change self.window.tintColor in -application:didFinishLaunchingWithOptions:.

More elegant way, in my opinion, is to set Global Tint in File Inspector in your Storyboard while nothing is selected. This way your -application:didFinishLaunchingWithOptions: is cleaner.

Global Tint in File Inspector

totocaster
  • 6,243
  • 5
  • 37
  • 46
  • any custom xibs are somehow not affected by both `UIWindow`'s `tintColor` property or the Global tint as you suggest. – atastrophic Sep 29 '15 at 22:08
  • not sure why changing storyboard option did not work, but `self.window?.tintColor = UIColor(netHex: 0xc0392b)` did. – Salah Alshaal Aug 15 '16 at 15:18
  • 2
    That would be amazing if Xcode was functional. Probably this will work on Xcode release 345. Today, as expected, Xcode craps on my head and do nothing. I wish Apple fires satan from the position of head of developer tools in the near future. – Duck Aug 20 '17 at 22:49
  • I feel you bro/sis. – Nestor Oct 08 '20 at 22:52
12

You can specify a tint color for the entire app by setting the window’s tint property. To do this, you could use code similar to the following:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window.tintColor = [UIColor purpleColor];
    return YES;
}
5

Updated for Swift 2.2

You can do this from anywhere like this:

// Get app delegate
let sharedApp = UIApplication.sharedApplication()

// Set tint color
sharedApp.delegate?.window??.tintColor = UIColor.green()

Or if you're trying to do this from AppDelegate,

self.window?.tintColor = UIColor.green()
Tulio Troncoso
  • 306
  • 5
  • 6
2

Updated for Swift 5

Write in the App Delegate :

self.window?.tintColor = UIColor.green
Stanislas Heili
  • 295
  • 2
  • 10
0
 UIView.appearance().tintColor = .green

same as this but in Swift

Ali
  • 2,427
  • 22
  • 25
0

In modern UIScene based apps you must iterate through all windows from all scenes to set the tintColor for the whole running app, with code like this:

for scene in UIApplication.shared.connectedScenes {
    if let windows = (scene as? UIWindowScene)?.windows {
        for window in windows {
            window.tintColor = .green
        }
    }
}
Ely
  • 8,259
  • 1
  • 54
  • 67
-1

Following things DID NOT WORKED for me:

navigationItem.backBarButtonItem?.tintColor = Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR

navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR], for: .normal)

self.navigationController?.navigationBar.barStyle = UIBarStyle.black

navigationController?.navigationBar.barTintColor = Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR

navigationController?.navigationBar.tintColor = Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR

navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR]

Following WORKED :

  1. SET THE GLOBAL TINT COLOR FROM STORYBOARD.

OR

  1. SET THE TINT COLOR OF THE WINDOW

FOR WHOLE APP:

let sharedApp = UIApplication.sharedApplication()
sharedApp.delegate?.window??.tintColor = UIColor.green()

FOR SPECIFIC CONTROLLER:

set tint color of window while initialization and set back the default tint color of the app while deinitialization.

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        let window = UIApplication.shared.windows.first
        window?.tintColor = Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        let window = UIApplication.shared.windows.first
        window?.tintColor = Theme.light.healthKit.BACK_BUTTON_TITLE_COLOR
    }

    deinit {
        let window = UIApplication.shared.windows.first
        window?.tintColor = Theme.light.App.DEFAULT_TINT_COLOR
    }
Shubham Ojha
  • 461
  • 5
  • 17