How do i keep UISwitch state when changing ViewControllers? - ios

When I move from one view controller to another, the switch on the first controller resets itself and does not retain its state.
How can I make it save its state when come back to it after viewing other controllers? And how do I make it save its state after closing the app. I have looked at the various stackOverflow questions and responses and the apple documentation, but nothing seems to work.
Here is my class for the View Controller that has the switch.
class Days: UIViewController {
#IBOutlet weak var switchButton: UISwitch!
var switchState = true
let switchKey = "switchState"
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func saveSwitchPressed(sender:AnyObject) {
if self.switchButton.on {
self.switchState = true
NSUserDefaults.standardUserDefaults().setBool(self.switchState, forKey: switchKey)
NSUserDefaults.standardUserDefaults().synchronize()
println(NSUserDefaults.standardUserDefaults().boolForKey(switchKey))
} else {
self.switchState = false
NSUserDefaults.standardUserDefaults().setBool(self.switchState, forKey: switchKey)
NSUserDefaults.standardUserDefaults().synchronize()
println(NSUserDefaults.standardUserDefaults().boolForKey(switchKey))
}
}
}
I'm a beginner to Swift and generally Xcode. Thank you in advance for your time and help :)

Xcode 8.3 • Swift 3.1
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var switchButton: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
switchButton.isOn = UserDefaults.standard.bool(forKey: "switchState")
}
#IBAction func saveSwitchPressed(_ sender: UISwitch) {
UserDefaults.standard.set(sender.isOn, forKey: "switchState")
}
}

Since you're syncing the on/off state of the switch you could on viewWillAppear: or viewDidAppear: set the state of the switch to the value stored in NSUserDefaults
Something along the lines of
override func viewWillAppear(animated: Bool) {
self.switchButton.on = NSUserDefaults.standardUserDefaults().boolForKey(switchKey)
}

just after code connect UISwitch to IBoutlet.
class ViewController: UIViewController {
#IBOutlet weak var switchButton: UISwitch!
#objc func switchStateDidChange(_ sender:UISwitch!)
{
if (sender?.isOn == true){
print("on")
}
else {
print("off")
}
UserDefaults.standard.set(sender.isOn, forKey: "switchState")
UserDefaults.standard.synchronize()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
switchButton?.isOn = UserDefaults.standard.bool(forKey: "switchState")
switchButton?.addTarget(self, action: #selector(switchStateDidChange(_:)), for: .touchUpInside)
}
}

Related

How to Change an image in 2nd View Controller using a Button in 1st View Controller

I have stetted up switch in my First View Controller and assigned the following action to it :-
class ThirdViewController: UIViewController {
#IBOutlet weak var Image: UIImageView!
#IBOutlet weak var playerNum1Button: UIButton!
#IBOutlet weak var toggleSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
self.toggleSwitch.setOn(UserDefaults.standard.bool(forKey: "toggleState"), animated: true)
}
#IBAction func numPlayers1(_ sender: Any) {
performSegue(withIdentifier: "3to8segue", sender: self)
}
IBAction func toggleSwitch(_ sender: UISwitch) {
if (toggleSwitch.isOn == true) {
Image.image = UIImage(named: "Night")
}
else {
Image.image = UIImage(named: "background")
}
UserDefaults.standard.set(sender.isOn, forKey: "toggleState")
}
It is Able to change the image in the First View Controller. But, how can I get that switch to change the image in 2nd View controller as well when it is turned on? Thanks for the help!
Using Notification Center
Example:
In FirstViewController:
#IBAction func onPressButton(_ sender: UIButton) {
UserDefaults.standard.set(sender.isSelected, forKey: "pressedButton")
NotificationCenter.default.post(name: "changeImageBackground", object: nil)
}
In SecondViewController:
NotificationCenter.default.addObserver(target: self, selector: #selector(didChangeImageBackground), name: "changeImageBackground", object: nil)
#objc func didChangeImageBackground() {
let changed = UserDefaults.standard.bool(forKey: "pressedButton")
if changed {
// image when pressed
} else {
// image when haven't pressed
}
}

How can I stop the video background when I move to another viewcontroller?

How can I stop the video background when I move to another UIViewController?
because when I move to another UIViewController, the video and background music continue to be played, and when I go back to the main page two videos overlap. so I would like the video and the music to stop when I move to another UIViewController, such as when I move in the UIViewController for the sign up
import UIKit
import SwiftVideoBackground
import Firebase
import FirebaseAuth
class ViewController: UIViewController {
private let videoBackground = VideoBackground()
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var mute_img: UIImageView!
#IBOutlet private var muteSwitch: UISwitch!
#IBAction func `switch`(_ sender: UISwitch) {
if (sender.isOn == true)
{
mute_img.isHidden = false
videoBackground.isMuted = true
}
else
{
mute_img.isHidden = true
videoBackground.isMuted = false
}
let shouldMute = sender.isOn
videoBackground.isMuted = shouldMute
UserDefaults.standard.set(shouldMute, forKey:"isMuted")
}
override func viewDidLoad() {
super.viewDidLoad()
let userDefaults = UserDefaults.standard
let shouldMute = userDefaults.bool(forKey: "isMuted")
videoBackground.play(view: view, videoName: "intro", videoType:
"mp4", isMuted: shouldMute, willLoopVideo : true)
muteSwitch.isOn = shouldMute
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == usernameField {
passwordField.becomeFirstResponder()
} else if textField == passwordField {
textField.resignFirstResponder()
}
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Forward navigation :
videoBackground.pause()
Back navigation :
videoBackground.resume()
As per the Documentation:
You can simply use the pause()
When leaving the Controller
videoBackground.pause()
When Back to Controller:
videoBackground.resume()

swift - how to save switch, even I change TableViews

import UIkit
// ViewController file
class ViewController: UITableViewController, UIViewController{
#IBAction func aaaSwitch(_ sender: UISwitch) {
if (sender.isOn == true)
{
ClickCounterA+=2
UserDefaults.standard.set(aaaSwitch, forKey: "aaaSwitch")
UserDefaults.standard.bool(forKey: "aaaSwitch")
defaults.set(aaaSwitch, forKey: "aaaSwitch")
}
else
{
defaults.set(aaaSwitch, forKey: "aaaSwitch")
}
}
I change the switch(aaaSwitch) in tableview and move to another tableview. After that, I return to the first tableview, the switch is the statement before I change. In other words, I can't save the switch statement.
The problem is you're passing aaaSwitch, the method, into the UserDefaults set calls. You want to be passing in a value, in this case a boolean value.
UserDefaults.standard.set(sender.isOn, forKey: "aaaSwitch")
If you really wanted to archive your entire UISwitch, you'd need to first convert it to an NSData (and you'd likely have to come up with an algorithm for doing so). And I can see no point in ever wanting to do that. Surely you just want to persist its on/off state, so use the above code.
class ViewController: UITableViewController, UIViewController{
#IBOutlet weak var aaaswitch: UISwitch!
override func viewWillAppear(_ animated: Bool) {
aaaswitch.isOn = UserDefaults.standard.bool(forKey: "aaaSwitch")
}
#IBAction func aaaSwitch(_ sender: UISwitch) {
if (sender.isOn == true)
{
....
}
else
{
....
}
UserDefaults.standard.set(sender.isOn, forKey: "aaaSwitch")
}
}

Is hidden not working on image views in Swift 3?

#IBOutlet weak var allStocksSelected: UIImageView!
#IBOutlet weak var shortStocksSelected: UIImageView!
#IBOutlet weak var longStocksSelected: UIImageView!
#IBOutlet weak var myStocksTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myStocksTableView.delegate = self
myStocksTableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
self.shortStocksSelected.isHidden = true
self.longStocksSelected.isHidden = true
self.allStocksSelected.isHidden = true
}
#IBAction func allStocksButtonPressed(_ sender: Any) {
print("ALL!")
self.stockTypeChanged(stockType: allStocksSelected)
}
#IBAction func shortStocksButtonPressed(_ sender: Any) {
print("SHORT!")
self.stockTypeChanged(stockType: shortStocksSelected)
}
#IBAction func longStocksButtonPressed(_ sender: Any) {
print("LONG!")
self.longStocksSelected.isHidden = false
self.shortStocksSelected.isHidden = true
self.allStocksSelected.isHidden = true
//stockTypeChanged(stockType: longStocksSelected)
}
#IBAction func addNewStockButtonPressed(_ sender: Any) {
}
#IBAction func signOutButtonPressed(_ sender: Any) {
}
private func stockTypeChanged(stockType: UIImageView) {
let stockTypes: [UIImageView] = [allStocksSelected, shortStocksSelected, longStocksSelected]
for (stock) in stockTypes {
if (stock == stockType) {
stock.isHidden = false
} else {
stock.isHidden = true
}
}
}
As shown from my code above, I am basically just trying to hide and show certain image views when buttons are pressed.
I am 100% sure that all of the buttons actions and IB outlets are properly connected, yet the image views are still not hiding and showing, and I cannot figure out why.
I was running into this same issue. Placing your isHidden code to execute on the main thread should solve the problem.
DispatchQueue.main.sync {
}

Disable Button from another view controller with a switch with swift

Ok so I am trying to make it when the user flips the cheat mode switch it will disable the answerButton. I did try to set the button to disable near the bottom however it does not appear to do anything. I added the print("") to see if it would print in the console however nothing was printed. I a unsure what is wrong here.
I have pasted my code below.
import Foundation
import UIKit
class SettingsController: UITableViewController {
#IBOutlet weak var cheatSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
cheatSwitch.isOn = UserDefaults.standard.bool(forKey: "switchState")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func saveSettings(_ sender: UISwitch) {
UserDefaults.standard.set(cheatSwitch.isOn, forKey: "switchState")
UserDefaults.standard.synchronize()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let mainView : ViewController = segue.destination as! ViewController
if cheatSwitch.isOn == true {
print("turn off button")
mainView.btnAnswer.isEnabled = false;
}
else {
print("turn on button")
mainView.btnAnswer.isEnabled = true;
}
}
}
You are saving the value UISwitch's state in UserDefaults so you can use its value in ViewController's method viewDidApper.
override func viewDidAppear(_ animated: Bool) {
self.btnAnswer.isEnabled = !UserDefaults.standard.bool(forKey: "switchState")
}
Note: There is no need to add prepareForSegue in your SettingsController because it will never called when you press back button of NavigationController so consider to remove it.

Resources