Swift ViewController doesn't refresh background color - ios

I have a MainView Controller and a second SettingsView Controller.
In SettingsView controller, I let user select a background color, save it and move back to MainView Controller.
I use Navigation controller segue to move from Main to Settings and use dismissViewControllerAnimated to move back to Main.
My problem is when I set background for main view, it doesn't show up.
But if I close and restart app then it comes up correctly.
Is it because Main view is already open and not refreshed back?
Here is the code:
Settings:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("theme", forKey: "BackgroundColor")
Main:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clearColor()
var backgroundLayer = Util.GetTheme()
backgroundLayer.frame = view.frame
view.layer.insertSublayer(backgroundLayer, atIndex: 0)
}

As per your requirement, you need to move the code for changing color to viewWillAppear method. Since viewDidLoad will be called only once at the time when it get loaded to memory. viewWillAppear will be called each time it will come to foreground or visible to user.
But where you are saving selected color and applying the saved color?

Try This code :
class Colors {
let colorTop = UIColor(red: 192.0/255.0, green: 38.0/255.0, blue: 42.0/255.0, alpha: 1.0).CGColor
let colorBottom = UIColor(red: 35.0/255.0, green: 2.0/255.0, blue: 2.0/255.0, alpha: 1.0).CGColor
let gl: CAGradientLayer
init() {
gl = CAGradientLayer()
gl.colors = [ colorTop, colorBottom]
gl.locations = [ 0.0, 1.0]
}
}

Related

Set background in UIViewController inside navigation controller

I want to set my background color fullscreen (includes navigation bar and status bar also) with gradient color. Right now, I made this by creating gradient
func setDefaultColorBackground() {
let colorTop = UIColor(hexString: "804b8a").cgColor
let colorBottom = UIColor(hexString: "42074b").cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [ colorTop, colorBottom]
gradientLayer.locations = [ 0.0, 1.0]
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at: 0)
}
So I added layer in my view in ViewController. It works but it does't covered up the status bar and navigation bar. See this image:
I think the background only fill the view under navigation bar. Anyway, I am using .xib and load it up manually in my view controller class.
Is there any ideas how to do it? Thank you so much!
I guess to change the color of the navigation bar you have to write the code for it also something like this :
UINavigationBar.appearance().barTintColor = UIColor.redColor()
or whatever color you want to provide :
UINavigationBar.appearance().barTintColor = UIColor(red: 0, green: 0/255, blue: 205/255, alpha: 1)
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]
I hope it was helpful to you. Happy Coding :)

Change viewController BG color based off another view controller

So I need some help for a project. I have a simple tab bar SVC where the first view is a timer and the second is a settings page. On the settings page I've setup a struct with an array of colors, then when a user clicks a button a random color in the array is called and applied to the back ground. This part works just as I Intended. What I'd like to do is then apply that color to the background of the second view.
Here is the settings code
import UIKit
import GameKit
public var randomColor = UIColor()
class SettingsViewController: UIViewController {
#IBOutlet weak var pushMe: UIButton!
let colorProvider = BackgroundColorProvider()
#IBAction func pushMeChange(_ sender: Any) {
randomColor = colorProvider.randomColorBG()
print (randomColor.superclass as Any)
view.backgroundColor = randomColor
}
struct BackgroundColorProvider {
let colors = [
UIColor(red: 90/255.0, green: 187/255.0, blue: 181/255.0, alpha: 1.0), // teal color
UIColor(red: 222/255.0, green: 171/255.0, blue: 66/255.0, alpha: 1.0), // yellow color
UIColor(red: 223/255.0, green: 86/255.0, blue: 94/255.0, alpha: 1.0), // red color
UIColor(red: 239/255.0, green: 130/255.0, blue: 100/255.0, alpha: 1.0), // orange color
UIColor(red: 77/255.0, green: 75/255.0, blue: 82/255.0, alpha: 1.0), // dark color
UIColor(red: 105/255.0, green: 94/255.0, blue: 133/255.0, alpha: 1.0), // purple color
UIColor(red: 85/255.0, green: 176/255.0, blue: 112/255.0, alpha: 1.0), // green color
]
func randomColorBG() -> UIColor {
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: colors.count)
return colors[randomNumber]
}
}
}
Then I have this in the main viewController I pulled from here:
Changing background color of all views in project from one view controller?
The function does error below doesn't error out however I'm a noob at best, I'm not sure how the bell should work and i doubt its even being called. Any help is appreciated.
// bringing in background color from SettingsViewController
func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "Load View") {
// pass data to next view
let viewController:SettingsViewController = segue!.destination as! SettingsViewController
viewController.view.backgroundColor = self.view.backgroundColor
}
}
Swift has this neat feature called a singleton that can be used to manage "settings" across a list of view controllers. In the viewDidLoad() method of the timer view you can set the view's background color to singleton.backgroundColor. In the settings view, when the user selects a new color, it should set singleton.backgroundColor = newColorThatUserChose. This way, when the user switches back to the Timer View, the color will automatically switch.
As shown in the link above, a singleton can be created like this:
class Settings {
static let sharedInstance = Settings()
var backgroundColor = UIColor.White // set to white by default.
}
Then in the viewDidLoad method for the Timer View:
self.view.backgroundColor = Settings.sharedInstance.backgroundColor
Finally in the SettingsViewController when the user chooses a new color:
var color = [UIColor.White, UIColor.Black, UIColor.Blue, UIColor.Green........]
Settings.sharedInstance.backgroundColor = color[x] // where x is the index that was chosen.
This will allow the views to change automatically based on the apps settings. To ensure that this works in all of the views that you would like to change the color for,
self.view.backgroundColor = Settings.sharedInstance.backgroundColor
should be placed in every UIViewController.
To further abstract this, you can create a custom class called GeneralUIViewController which is a class of type UIViewController and has the above code in its viewDidLoad method. After doing this every UIViewController should have its class set to GeneralUIViewController. This will make it so you only need to set the background color in one file and every view controller in your project will automatically inherit setting its background color to what the User has chosen in the settings page of this application.
These preferences should probably be saved when the application is reopened so CoreData can be used for this. I'd check out this link for more information.

How to set background of a view (UITableview) with dynamic cells?

I am trying to set a background Colour to the view occupied by the UITableViewCell. I have dragged an outlet and have a gradient layer which i return to it
extension CAGradientLayer{
func viewGradient(topColour:UIColor,bottomColour : UIColor) -> CAGradientLayer{
let gradientColor: [CGColor] = [topColour.cgColor, bottomColour.cgColor]
let gradientLocations: [Float] = [0.0/1.0]
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = gradientColor
gradientLayer.locations = gradientLocations as [NSNumber]?
return gradientLayer
}
}
And i access this method in my viewDidLoad method of a view controller
let bottomColour = UIColor(red: (0.018), green: (0.38), blue: (0.64), alpha: 1.0)
let topColour = UIColor(red: (0.13), green: (0.63), blue: (0.67), alpha: 0.7)
let background = CAGradientLayer().viewGradient(topColour:topColour,bottomColour : bottomColour)
background.frame = self.view.bounds
self.view.layer.insertSublayer(background, at: 0)
myMenu.layer.insertSublayer(background, at: 0)
I have dynamic cells in my table view and as the number of cells increases the view slides down and i Have to scroll to see my cells.I have white spaces. Is there any way i can set the entire scrolling region to have my background gradient colour or am i missing something ?
Here is the screenshot of the images showing my exact problem
As commented above, UITableView has a backgroundView property.
In your viewDidLoad method, keep your background constant declared as is, then below add:
self.tableView.backgroundView = background
Hope that helps.

Run a function located in one UIViewController from a different controller

I currently have two UIViewControllers, a Calculation UIViewController, and a Settings UIViewController. I'm attempting to make a dark and light theme. In the Calculation VC, I have a theme function:
func setCandyTheme() {
print("Theme enabled!")
configureGradientBackground(UIColor(red: 0.14, green: 0.85, blue: 1.0, alpha: 0.8).CGColor, UIColor(red: 0.24, green: 0.65, blue: 1.0, alpha: 0.8).CGColor)
for view: UIView in containerViews {
view.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.18)
}
for textField: UITextField in textFields {
textField.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.20)
}
for textField: UITextField in weightTextFields {
textField.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.25)
}
}
In the Settings VC, I made a toggle for enabling the theme. When it's enabled, it sets the themeKey value (which works) and runs the setCandyTheme function.
func switchIsChanged(themeToggle: UISwitch) {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let calcViewController = storyBoard.instantiateViewControllerWithIdentifier("Calculate") as! ViewController
if themeToggle.on {
defaults.setValue("True", forKey: themeKey.key)
calcViewController.setCandyTheme()
}
else {
defaults.setValue("False", forKey: themeKey.key)
}
}
Unfortunately, the theme isn't applied but the "Theme enabled!" string is printed in the console. I assume it's running the function in the Settings VC rather than Calculation, which is why it's not being applied.
What's the solution for this? I've been at it for hours and any help would be much appreciated!
When you do the following, you are creating a new instance of that ViewController. Therefore, you are running your code on that other instance, not the one that is attached to the screen. Therefore, you are not changing what you think you are changing.
let calcViewController = storyBoard.instantiateViewControllerWithIdentifier("Calculate") as! ViewController
You can have ViewControllers call functions in other ViewControllers but you have to give it the ViewController to call, you cannot instantiate a new one.
You could just store the current theme in your AppDelegate or someplace like that. Then, when the calculator viewWillAppear fires, adjust the theme as needed.
I ended up finding a solution! The calculation view controller was not being refreshed after a self.dismissViewControllerAnimated(false, completion: nil), so what I ended up doing was create an Unwind Segue and set the theme in the function.
#IBAction func unwindToCalculation(segue: UIStoryboardSegue) {
if themeOn == defaults.stringForKey(themeKey.key) {
self.setCandyTheme()
}
}

PushViewController & set navigation bar color and title

I made a push function in a button:
#IBAction func prodButton(sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var secondViewController = CollectionViewController()
secondViewController = storyboard.instantiateViewControllerWithIdentifier("CollectionViewController") as! CollectionViewController
self.navigationController?.pushViewController(secondViewController, animated: true)
}
This button pushes to the secondViewController but when I looked at the navigation bar of the second view controller I noticed that it has set up a back button automatically. The problem is that this back button's color is light blue and it doesn't fit with my design. I tried to change it like that in viewDidAppear
self.navigationItem.leftBarButtonItem?.tintColor = UIColor.redColor()
and also the bar color:
self.navigationController?.navigationBar.barTintColor = UIColor(red: 65, green: 61, blue: 116, alpha: 1.0)
but there wasn't any change.
I'd be really thankful if somebody help me with that.
Thanks in advance.
Try to set your color one time, it will be the same color for everywhere after:
let navBar = UINavigationBar.appearance()
navBar.tintColor = UIColor.redColor()
You should put this code in AppDelegate. You could also set the barTint in Storyboard if you use it.
Use
//Func Alter color navigation bar
func AlteraCorNavigationBar(Navigation:UINavigationController){
Navigation.navigationBar.tintColor = CorTextoNavigationBar()
//Navigation.navigationBar.barTintColor = CorPredominante()
Navigation.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : CorTextoNavigationBar(), NSFontAttributeName : UIFont(name: "ArialHebrew-Light", size: 22)!]
}
//func CorPredominante()->UIColor{
//return UIColor.redColor()
//(rgba: "#ecf0f1")
// YOU CAN LIBRARY COLOR RGBA [HERE][1] AND USE UIColor(rgba: "#b6011a")
//}
func CorTextoNavigationBar()->UIColor{
return UIColor(red: 65, green: 61, blue: 116, alpha: 1.0)
}
for called in view controller:
class NewViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
AlteraCorNavigationBar(navigationController)
}
}
I found the mistake.
The colors shoud be devided by 255:
UINavigationBar.appearance().tintColor = UIColor(red: 149.0 / 255.0, green: 148.0 / 255.0, blue: 192.0 / 255.0, alpha: 0.5)
UINavigationBar.appearance().barTintColor = UIColor(red: 65.0 / 255.0, green: 61.0 / 255.0, blue: 116.0 / 255.0, alpha: 1.0)
Thank you all for the help ;)

Resources