jat
jat

Reputation: 337

iOS settings page helper class

I am trying to build a settings page helper class in order to simplify the setup of a settings page.

The idea would be that the class handles saving the state to UserDefaults and setting the initial state of any UISwitch.

Setting up a switch would just be a matter of setting a new switch to a class of "UISettingsSwitch" and adding the name of it to the accessibility label (it's the only identifier available as far as i'm aware).

So far I have :

import Foundation
import UIKit

class SettingsUISwitch: UISwitch {
    
    enum SettingsType {
        
        case darkMode, sound
        
    }
    
    func ison(type: SettingsType ) -> Bool {
        
        switch type {
    
        case .darkMode:
            
            return userDefaults.bool(forKey: "darkMode")
            
        case .sound:
            
            return userDefaults.bool(forKey: "sound")
        }
    
    }
    
    let userDefaults = UserDefaults.standard
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        initSwitch()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        initSwitch()
    }
    
    deinit {
    
    }
    
    func initSwitch() {
        
        addTarget(self, action: #selector(toggle), for: .valueChanged)
        
    }
    
    
    @objc func toggle(){
        
        userDefaults.setValue(self.isOn, forKey: self.accessibilityLabel!)
        
    }
}

Not an awful lot I know.

I can currently do :

 if settingsSwitch.ison(type: .darkMode) {
            
            print (settingsSwitch.ison(type: .darkMode))
            
            print ("ON")
            
        } else {
            
            print ("OFF")
        }

The accessibility label doesn't seem to be available in the init setup at any point, so setting up the initial state doesn't seem to be a possibility. Is it possible to set the initial state of the UISwitch this way ?

Ideally , I'd like to expose : settingsSwitch.darkMode.ison as a boolean ... but I can't figure that one out. Thanks for any help

Upvotes: 0

Views: 111

Answers (1)

jat
jat

Reputation: 337

I managed to use the restoration identifier to do the setup for the switch but I'd still love to remove the cases and the repeated calls to userDefaults

import Foundation
import UIKit

class UISwitchSettings: UISwitch {
    
    enum SettingsType: String, CaseIterable {
        
        case darkMode = "darkMode"
        case sound = "sound"
        
    }
    
    func ison(type: SettingsType ) -> Bool {
        
        switch type {
    
        case .darkMode:
            
            return userDefaults.bool(forKey: "darkMode")
            
        case .sound:
            
            return userDefaults.bool(forKey: "sound")
        }
    
    }
    
    let userDefaults = UserDefaults.standard
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        initSwitch()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        initSwitch()
    }
    
    deinit {
    
    }
    
    func initSwitch() {
        
        if let key = self.restorationIdentifier {
            
            // Logic needs changing if default switch is off
            
            if userDefaults.bool(forKey: key) || userDefaults.object(forKey: key) == nil {
                
                self.isOn = true
                
            } else {
                
                self.isOn = false
                
            }
        }
        
        addTarget(self, action: #selector(toggle), for: .valueChanged)
    }
    
    @objc func toggle(){
        
        userDefaults.setValue(self.isOn, forKey: self.restorationIdentifier!)
    }
}

Upvotes: 0

Related Questions