Swift 4中切换ViewController后保持开关状态,重启App恢复关闭的实现
解决开关状态:运行时保持,重启App重置为关闭
嘿,我明白你的需求了——开关打开后切到其他页面再回来要保持开启,但重启App必须回到关闭状态。你之前用UserDefaults来存状态的问题在于,UserDefaults是持久化到磁盘的,所以App重启后会读取之前保存的值,自然没法重置。咱们换个思路,用内存变量来存运行时的状态就行,具体实现看下面:
步骤1:定义内存级别的状态变量
在你的ViewController里添加一个实例变量,用来保存开关的当前状态,初始值设为false(关闭状态):
class YourViewController: UIViewController { @IBOutlet weak var switchOutlet: UISwitch! var isSwitchOn = false // 仅存在于App运行时的内存中,重启会重置 // 剩下的代码... }
步骤2:初始化开关并添加监听
在viewDidLoad里把开关初始状态和变量绑定,同时添加值变化的监听:
override func viewDidLoad() { super.viewDidLoad() switchOutlet.isOn = isSwitchOn // 监听开关值变化 switchOutlet.addTarget(self, action: #selector(switchValueChanged(_:)), for: .valueChanged) }
步骤3:处理开关状态变化
实现开关值变化的方法,实时更新内存变量:
@objc func switchValueChanged(_ sender: UISwitch) { isSwitchOn = sender.isOn // 这里不用存到UserDefaults,因为我们只需要运行时保持状态 }
步骤4:返回页面时同步状态
当从其他ViewController返回时,viewWillAppear会被调用,这里再同步一下开关状态(虽然导航栈里的VC不会被销毁,状态本来就保留,但加这一步更稳妥):
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) switchOutlet.isOn = isSwitchOn }
为什么这样可行?
- 内存变量
isSwitchOn只在App运行期间存在,一旦App退出重启,这个变量会重新初始化为false,开关自然回到关闭状态。 - 当你切换到其他ViewController时,当前VC会留在导航栈中,内存变量不会被释放,所以返回时状态依然保持你之前设置的样子。
如果你的场景是用present弹出其他页面,当前VC可能被暂时销毁的话,也可以用一个全局的单例来存运行时状态,但大部分导航栈的场景用上面的实例变量就完全够用啦。
内容的提问来源于stack exchange,提问作者Marcelo_M




