0

I am following this tutorial provided on Youtube for: How to Save Data with UserDefaults - Swift

https://www.youtube.com/watch?v=sUhq1vIrRbo

And I have this code that works for one page only and would like to know how to do the same exact thing (changing background color) but for my entire app pages based on the user's choice.

I have tried keeping the checkForStylePreference() in the viewDidLoad()of another page but it did not recognize it. I copy pasted the whole checkForStylePreference() but still other pieces of code were missing. Is the only way to do it is by copy pasting all of the methods of the viewController in all App pages? Or there is a much simpler way as a believe to reduce amount of code? Currently I can change BgColor from white to grey perfectly enter image description here but I don't know how to apply it for all.

This is the code of my NameViewController.swift (the one I've created for the page in the screenshot). Please note that I have 2 more swift files which are SAButton.swift and ConstantStyles.swift (for the colors)

class NameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        nameLbl.text = myString
        checkForStylePreference()

    }

    @IBAction func didChangeStyleSeg(_ sender: UISegmentedControl) {
        isDarkMode = sender.selectedSegmentIndex == 1
        saveStylePreference()
        updateStyle()
    }

    var myString = String()
    @IBOutlet weak var styleSegment: UISegmentedControl!
    @IBOutlet weak var nameLbl: UILabel!


        var isDarkMode = false
        let defaults = UserDefaults.standard


        struct Keys {
            static let preferDarkMode = "preferDarkMode"

        }


        func updateStyle(){

            UIView.animate(withDuration: 0.4){
               // self.view.backgroundColor = self.isDarkMode ? Colors.darkGrey : .white
               // UIColor(hue: 287/360, saturation: 15/100, brightness: 85/100, alpha: 1.0) 
        self.view.backgroundColor = self.isDarkMode ? Colors.lightGrey : .white

                //recent correct one
                // self.view.backgroundColor = self.isDarkMode ? Colors.darkGrey : .white

                //self.view.UIBackgroundFetchResult = self.isDarkMode? UIColor.grey : .white

            }
        }


        func saveStylePreference(){
            defaults.set(isDarkMode, forKey: Keys.preferDarkMode)


        }


        func checkForStylePreference(){
            let preferDarkMode = defaults.bool(forKey: Keys.preferDarkMode)
            if preferDarkMode{
                isDarkMode = true
                updateStyle()
                styleSegment.selectedSegmentIndex = 1


            }

        }


        // Do any additional setup after loading the view.
    }

Code of the SAButton.swift

class SAButton: UIButton {


    override init(frame: CGRect) {
        super.init(frame: frame)
        setupButton()
    }


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupButton()
    }


    private func setupButton() {
        setTitleColor(.white, for: .normal)
        backgroundColor     = Colors.lightBlue
        titleLabel?.font    = .boldSystemFont(ofSize: 20)
        layer.cornerRadius  = frame.size.height / 2
    }


}

Code of the ConstantStyles.swift

import UIKit

struct Colors {
    static let darkGrey  = UIColor(red: 40/255, green: 40/255, blue: 40/255, alpha: 1)
   // static let purple = UIColor(red: 212/255, green: 186/255, blue: 86/255, alpha: 1)
    static let lightBlue = UIColor(red: 89/255, green: 205/255, blue: 242/255, alpha: 1)
    static let darkPurple = UIColor(red: 242/255, green: 232/255, blue: 255/255, alpha: 1.0)
         // UIColor(hue: 287/360, saturation: 15/100, brightness: 85/100, alpha: 1.0)
    static let lightPurple = UIColor(red: 240/255, green: 229/255, blue: 255/255, alpha: 1.0)
    static let lightGrey = UIColor(red: 237/255, green: 237/255, blue: 237/255, alpha: 1.0)
        //UIColor(red: 249/255, green: 244/255, blue: 255/255, alpha: 1.0)

}

I believe it could be simple but I am new to Swift, I would like to know what part of code to keep exactly and where. Much appreciated.

Ps: Original project Source Code is provided below the Youtube Video.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Noor
  • 3
  • 4

2 Answers2

0

You can create a main class and inherit from it

class GeneralVC : UIViewController {
    override func viewDidLoad() {
        self.view.backgroundColor = .red // read color from userdefaults and set it here
    }
}
class ViewController: GeneralVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

Same applies to any UIKit component that you need to affect globally

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • I have tried your way by creating a GeneralVC and adding to it view load, it works perfectly if I keep = .red , however, I didn't know how to get the userDefault value.. – Noor Jun 18 '19 at 15:54
  • I have tried keeping the whole func checkForStylePreference(){ let preferDarkMode = defaults.bool(forKey: Keys.preferDarkMode) if preferDarkMode{ isDarkMode = true updateStyle() styleSegment.selectedSegmentIndex = 1 } } But it did not work as it needs many other pieces of code to be in the same page as well such as (the segment outlet, and the updateStyle() Please assist – Noor Jun 18 '19 at 15:54
  • Also I have kept the following code: self.view.backgroundColor = UserDefaults.standard.string(forKey: "Key") It gave me this error: Cannot assign value of type 'String?' to type 'UIColor?' – Noor Jun 18 '19 at 18:58
  • see this https://stackoverflow.com/questions/34366171/how-do-i-save-a-uicolor-with-userdefaults – Shehata Gamal Jun 18 '19 at 20:25
0

Another interesting way to do it is to use Appearance:

Perhaps you can use UIViewControllerWrapperView as a parent.

UIView.appearance(whenContainedInInstancesOf: [UIViewControllerWrapperView]) // UIViewControllerWrapperView might be private. In that case it might take some wizardry to get it to work

Another way to do it is to set it when the UITabBarController or UINavigationController presents a new UIViewController. You can do this by subclassing them.

The reason why I don't like subclassing is that you force a subclass for just one simple thing. If you only do it in a few navigation based ones it's much easier and also easier to override with extensions instead of everything through subclassing.

Lucas van Dongen
  • 9,328
  • 7
  • 39
  • 60