iOS UILabel.appearance().textColor is not available - ios

I am trying to change default text color for all labels in my app. I have tried to use UILabel.appearance().textColor, but it's not available for me. Can somebody advise what am I doing wrong? I have checked a lot of questions on SO, the latest one is this. And as per description it's available.
If I changed background color - it works. Tried to change tintColor - no effect. Why? Was it removed from UIAppearance protocol?
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
var smStore: SMStore?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// UIAppearance configuring
let tintColor = UIColor.white
//let backgroundColor = UIColor(red: 5, green: 72, blue: 149, alpha: 1)
let backgroundColor = UIColor.black
// Global tintColor
window?.tintColor = tintColor
// UIViews
UIView.appearance().tintColor = tintColor
UIView.appearance().backgroundColor = backgroundColor
// UINavigationBars
UINavigationBar.appearance().tintColor = tintColor
UINavigationBar.appearance().backgroundColor = tintColor
// UITableViews
UITableView.appearance().backgroundColor = backgroundColor
UITableViewCell.appearance().backgroundColor = backgroundColor
UITableViewCell.appearance().tintColor = tintColor
// UILabels
UILabel.appearance().backgroundColor = UIColor.green
...
}
Xcode 9, Swift 4.

Just type it in. It compiles.
UILabel.appearance().textColor = .red

Related

barTintColor not applied when NavigationBar is Large Titles

I'm updating an app that was compiled on Xcode 10 and running fine up through iOS 13. I wanted to make some changes so recompiled on Xcode 11 and now have a problem with the barTintColor.
If 'Large Titles' is set to 'Always' my custom barTintColor is not applied -- I just get the default gray. If 'Large Titles' is set to 'Never', my custom barTintColor is applied as expected. If 'Large Titles' is set to 'Automatic', the NavBar is default gray when Large Titles are shown and my custom color when small titles are shown. For example, when the TableView below my nav bar is pushed up, the default large title switches to small title, and my NavBar changes color. Normal behavior would be for it always to be my custom color.
The relevant code from my ViewController class, with the last line being the one that sets the barTintColor:
override func viewDidLoad() {
super.viewDidLoad()
setDelegates()
setTableViewHeightForCollapsingHeaders()
setNavigtionBarItems()
doSplitViewManagement()
}
override func viewWillAppear(_ animated: Bool) {
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)
updateUI()
}
fileprivate func setNavigtionBarItems() {
//set up UI buttons
navigationItem.leftBarButtonItem = editButtonItem
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
navigationController?.navigationBar.barTintColor = UIColor(hex: 0x5da0a2)
}
Any idea why the behavior changed, and how to fix it?
Apple's documentation that glotcha pointed to was critical to solving the problem although there was a bit more to it. Here's the updated version of my setNavigationBarItems() that works in iOS 13:
fileprivate func setNavigtionBarItems() {
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = myBackgroundColor
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
//navigationController?.navigationBar.compactAppearance = appearance
} else {
// Fallback on earlier versions
navigationController?.navigationBar.barTintColor = myBackgroundColor
}
}
A key point in my case was that my Navigation Bar is set (in Autolayout) with 'Large Titles' as 'Automatic'. This makes it necessary to include the .scrollEdgeAppearance line so that the custom appearance applies when it transitions from large to compact. It turned out the .compactAppearance line was not required because I use the same color for both. If I wanted different appearance settings for large and compact then a line with .compactAppearance would also be useful.
There's a new API since iOS 13 https://developer.apple.com/documentation/uikit/uinavigationbarappearance
The backgroundColor property you're looking for is in the super class
https://developer.apple.com/documentation/uikit/uibarappearance
Some extra sample code here
https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar
If you want a single place to do it for the whole app:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let barBackgroundColor = UIColor(displayP3Red: 47/255, green: 54/255, blue: 64/255, alpha: 1.0)
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = barBackgroundColor
appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
return true
}

Eureka Forms: How to change form global tint colour

I am using Eureka to implement a simple form in my project. The form seems to have blue tint in the tint bar buttons above the keyboard and I am unsure how to change it.
Is there a way to make the "Done" label green like the rest of my UI?
Updated Eureka 4.3.x
You should override a variable customNavigationAccessoryView in your controller
override var customNavigationAccessoryView: (UIView & NavigationAccessory)? {
// The width might not be correctly defined yet: (Normally you can use UIScreen.main.bounds)
let navView = NavigationAccessoryView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44.0))
navView.barTintColor = UIColor.MaterialColors.category3
navView.tintColor = UIColor.white
return navView
}
Here you go and fix the colour of Done Label.
override NaviagtionAccessoryView Instance as navigationAccessoryView below
navigationAccessoryView.tintColor = "Your Colour"
navigationAccessoryView.backgroundColor = "Your Colour"
navigationAccessoryView.doneButton.tintColor = "Your Colour"
More Here
You can set a default tint color for all UIView instance by
UIView.appearance().tintColor = .red
appearance() is a method in UIAppearance protocol. UIView and its subclasses confirm to this protocol. You can also do
UIButton.appearance().tintColor = .green
Add the below line in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
self.window?.tintColor = UIColor.black // You can set it to which color you want.
return true
}
All the tint color of the whole app will be changed to the given color.
This works for me perfectly:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
NavigationAccessoryView.appearance().tintColor = /* your color here */
}

Customize every single UISearchBar From AppDelegate Not Working

I have this code below in my AppDelegate.swift:
func customizeBars() {
let bartintColor = UIColor(colorLiteralRed: 20/255, green: 160/255, blue: 160/255, alpha: 1)
UISearchBar.appearance().tintColor = bartintColor
window!.tintColor = UIColor(red: 10/255, green: 80/255, blue: 80/255, alpha: 1)
}
I call this function (customizeBars()) in my didFinishLaunchingWithOptions method:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
customizeBars()
return true
}
I also have this in the UISearchBArDelegate if it makes a difference:
func position(for bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.topAttached
}
But for some reason when I run my app it doesn't change the tintColor of any of the UISearchBars I have in my app or my window tint color. Is there something I am doing wrong?
You can change the search bar color using this below line of code -
UISearchBar.appearance().barTintColor = UIColor.red // Change the color here
But I saw that, tint color(for cancel button, search icon and text color) is not working in iOS 10, swift 3.
It used to work before in older versions. Let me try if i can find something to change the tint color of search bar.

Change Status Bar Background Color in Swift 3

In XCode 7.3.x ill changed the background Color for my StatusBar with:
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.sharedApplication().valueForKey("statusBarWindow")?.valueForKey("statusBar") as? UIView else {
return
}
statusBar.backgroundColor = color
}
But it seems that this is not working anymore with Swift 3.0.
Ill tried with:
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = (UIApplication.shared.value(forKey: "statusBarWindow") as AnyObject).value(forKey: "statusBar") as? UIView else {
return
}
statusBar.backgroundColor = color
}
But it gives me:
this class is not key value coding-compliant for the key statusBar.
Any Ideas how to change it with XCode8/Swift 3.0?
extension UIApplication {
var statusBarView: UIView? {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
return nil
}
}
UIApplication.shared.statusBarView?.backgroundColor = .red
Update for iOS 13
App called -statusBar or -statusBarWindow on UIApplication: this code
must be changed as there's no longer a status bar or status bar
window. Use the statusBarManager object on the window scene instead.
Refer to How to change the status bar background color and text color on iOS 13?
"Change" status bar background color:
let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)
let statusBarColor = UIColor(red: 32/255, green: 149/255, blue: 215/255, alpha: 1.0)
statusBarView.backgroundColor = statusBarColor
view.addSubview(statusBarView)
Change status bar text color:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Update: please note that the status bar frame will change when the view is rotated. You could update the created subview frame by:
Using the autoresizing mask:
statusBarView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
Observing NSNotification.Name.UIApplicationWillChangeStatusBarOrientation
Or overriding viewWillLayoutSubviews()
With using Swift 3 and 4 you can use the code snippet on below. It finds the view from UIApplication using valueForKeyPath as set it's background color.
guard let statusBarView = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else {
return
}
statusBarView.backgroundColor = UIColor.red
Objective-C
UIView *statusBarView = [UIApplication.sharedApplication valueForKeyPath:#"statusBarWindow.statusBar"];
if (statusBarView != nil)
{
statusBarView.backgroundColor = [UIColor redColor];
}
For Xcode 9 and iOS 11:
The style of the status bar we will try to achieve is a status bar with white content. Go to the ViewController.swift file and add the following lines of code.
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Or from project settings option you can change status bar's style:
Next, go back to the Storyboard, Select the View Controller and in the Editor menu Select Embed in Navigation Controller. Select the Navigation Bar and in the Attribute Inspector set the Bar Tint color to red. The Storyboard will look like this.
Build and Run the project, The content of the status bar is dark again, which is the default. The reason for this is, iOS asked for the style of the status bar of the navigation controller instead of the contained view controller.
To change the style of all navigation controller inside the app, change the following method in the AppDelegate.swift file.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().barStyle = .blackOpaque
return true
}
Build and Run the Project again, this time the content of the status bar changed to white.
I have a custom solution for changing status bar on iOS 13 and below. Here is how to do that:
if #available(iOS 13.0, *) {
let app = UIApplication.shared
let statusBarHeight: CGFloat = app.statusBarFrame.size.height
let statusbarView = UIView()
statusbarView.backgroundColor = UIColor.red
view.addSubview(statusbarView)
statusbarView.translatesAutoresizingMaskIntoConstraints = false
statusbarView.heightAnchor
.constraint(equalToConstant: statusBarHeight).isActive = true
statusbarView.widthAnchor
.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true
statusbarView.topAnchor
.constraint(equalTo: view.topAnchor).isActive = true
statusbarView.centerXAnchor
.constraint(equalTo: view.centerXAnchor).isActive = true
} else {
let statusBar = UIApplication.shared.value(forKeyPath:
"statusBarWindow.statusBar") as? UIView
statusBar?.backgroundColor = UIColor.red
}
Gist
Also, check the article iOS 13 How to Change StatusBar Color?
One last thing, you can still change statusbar style with :
override var preferredStatusBarStyle : UIStatusBarStyle {
return UIStatusBarStyle.lightContent
//return UIStatusBarStyle.default // Make dark again
}
For iOS 11 and Xcode 9 use the following steps.
create an extention to UIApplication class:
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
In your class or wherever you want to change the Status bar's background color:
UIApplication.shared.statusBarView?.backgroundColor = .red
For light content or dark content of status bar simply go to Info.plist and add the following value row with value NO.
View controller-based status bar appearance
Now just set the light content or whatever you need in the General Tab of your project's settings.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any] ?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().barStyle = .blackOpaque
return true
}
This works for me, as my navigation barTintColor was black and unable to see the status bar.
When set above code it didFinishLaunch status bar appears in white.
write this in first view controller:
UIApplication.shared.statusBarUIView?.backgroundColor = .white
extension UIApplication {
var statusBarUIView: UIView? {
if #available(iOS 13.0, *) {
let tag = 38482458385
if let statusBar = self.keyWindow?.viewWithTag(tag) {
return statusBar
} else {
let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)
statusBarView.tag = tag
self.keyWindow?.addSubview(statusBarView)
return statusBarView
}
} else {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
}
return nil
}
}
I made this extension to change color of status bar. It's not dependent on the key.
So it is much safer to use
public extension UIViewController {
func setStatusBar(color: UIColor) {
let tag = 12321
if let taggedView = self.view.viewWithTag(tag){
taggedView.removeFromSuperview()
}
let overView = UIView()
overView.frame = UIApplication.shared.statusBarFrame
overView.backgroundColor = color
overView.tag = tag
self.view.addSubview(overView)
}
}
Here is usage anywhere in viewcontroller:
setStatusBar(color: .red)
Try this
Goto your app info.plist
Set View controller-based status bar appearance to NO
Set Status bar style to UIStatusBarStyleLightContent
Then Goto your app delegate and paste the following code where you set your Windows's RootViewController.
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 20)];
view.backgroundColor=[UIColor blackColor];
[self.window.rootViewController.view addSubview:view];
}
Previous Code:-
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = color
}
My application got a crash show reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'
Updated Code-
if #available(iOS 13.0, *) {
let statusBar = UIView(frame: UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero)
statusBar.backgroundColor = UIColor.init(red: 237.0/255.0, green: 85.0/255.0, blue: 61.0/255.0, alpha: 1.0)
UIApplication.shared.keyWindow?.addSubview(statusBar)
} else {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.init(red: 237.0/255.0, green: 85.0/255.0, blue: 61.0/255.0, alpha: 1.0)
}
This code is working swift 5.2
enter image description here
You can set background color for status bar during application launch or during viewDidLoad of your view controller.
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
// Set upon application launch, if you've application based status bar
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
return true
}
}
or
// Set it from your view controller if you've view controller based statusbar
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
}
}
Here is result:
The possible solution is adding view that will be used as background of statusBar on your viewController:
let frame = screenController.view.convert(UIApplication.shared.statusBarFrame, to: screenController.view)
let backview = UIView(frame: frame)
backview.backgroundColor = backgroundColor
screenController.view.addSubview(backview)
screenController.view.bringSubviewToFront(backview)
Add following code in your extension file to edit your status bar in swift 4 and Above:
extension UIApplication {
var statusBarView: UIView? {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
return nil
}
}
now, we can edit status bar by adding following line in our ViewController class:
UIApplication.shared.statusBarView?.backgroundColor = <Your Color name>
ex: UIApplication.shared.statusBarView?.backgroundColor = .red
Hope, this will be helpful.
Thanks
IOS 15, Xcode 13.2.1, Swift 5
I was able to get this to work without errors or warnings using the following:
func statusBarColor() {
if #available(iOS 13.0, *) {
let statusBar2 = UIView()
if UIApplication.shared.currentScene?.statusBarManager!.statusBarFrame != nil {
statusBar2.frame = (UIApplication.shared.currentScene?.statusBarManager!.statusBarFrame)!
statusBar2.backgroundColor = UIColor.init(named: "BackGroundColor")
UIApplication.shared.windows.first?.addSubview(statusBar2)
}
} else {
let statusBar2: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
statusBar2.backgroundColor = UIColor.init(named: "BackGroundColor")
}
}
Use: Call the function in viewDidLoad for single scene applications or applications with only a single statusBar color change needed. For applications with multiple scenes calling for different statusBar colors I recommend calling the function in viewWillAppear.

Can't read titleTextAttributes on appearance for UITabBarItem

I am working on styling the app I'm building. I want to apply some system-wide styling (fonts) to the tab bar and then in some instances style things like colour. I'm running into two problems:
When you set any titleTextAttributes using setTitleTextAttributes:forState: on an instance of a UITabBar, it immediately ignores any titleTextAttributes set on the appearance proxy (including keys that were not set on the instance, but set on the appearance proxy).
// AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UITabBarItem.appearance().setTitleTextAttributes([
NSFontAttributeName: UIFont(name: "Lato-Regular", size: 20.0)!
], forState: .Normal)
}
// Later on in a ViewController that has a UITabBar
override func viewDidLoad() {
myTabBar.setTitleTextAttributes([
NSForegroundColorAttributeName: UIColor.blueColor()
], forState: .Normal)
// Tab bar items now have blue text, but Helvetica Neue font
// We've lost the appearance proxy font (Lato-Regular)
}
In order to fix (1) I was just going to copy the titleTextAttributes from the appearance proxy and then overwrite them with whatever attributes I wanted to apply on the instance. Eg.
// AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UITabBarItem.appearance().setTitleTextAttributes([
NSFontAttributeName: UIFont(name: "Lato-Regular", size: 20.0)!
], forState: .Normal)
}
// Later on in a ViewController that has a UITabBar
override func viewDidLoad() {
var attributes = UITabBarItem.appearance().titleTextAttributesForState(state) ?? [NSObject: AnyObject]()
assert(attributes.count > 0, "Could not read titleTextAttributes set on appearance proxy!")
}
This is most annoying because you can read appearance proxy values on UINavigationBar just fine.
Any ideas?

Resources