1

In my app, I've got a scenario where I need to switch the UI theme design based on user type. For eg: In my Type1 user flow it goes like Registration Screen -> HomePage Screen and in my Type 2 user it should go like Registration Screen-> Contact Screen -> Home Page Screen. And the UI design and themes are different in the case of Type 2 user. For achieve this, below is my sample code flow which is implemented currently.

RegistrationViewController

(This view is available for both users but UI theme is different, like navigation bar color, bg color, button color, fonts, images etc)

override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }


private func setupViews(){

        if Utilities.isUserType1{
            setupViewsForType1User() //Adds themes for type 1 user
        } else {
            setupViewsForType2User() //Adds themes for type 2 user
    }

}

 @IBAction func continueAction(_ sender: Any) {

    if Utilities.isUserType1{
            goToContactView() //Goes to ContactViewController
        } else {
            gotToHomeView() //Goes to HomeViewController
    }

}

ContactViewController (This view is only available for type1 user)

override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }


private func setupViews(){

        //Setupviews 

}

 @IBAction func continueAction(_ sender: Any) {

            gotToHomeView()

}

HomeViewController (This view is available for both users but UI theme is different as mentioned in Registration)

override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }



private func setupViews(){

        if Utilities.isUserType1{
            setupViewsForType1User()
        } else {
            setupViewsForType2User()
    }

}

This works fine, but the problem here is now I've defined an isUserType in Utilities and its not perfectly scalable. For each flow and UI change, I need to put an if-else condition based on this parameter. So, now if I have another user type that needs to be added in the future I would again need another if-else statement and switch UI and flow based on that.

Is there any better approach to solve this problem?

Francis F
  • 3,157
  • 3
  • 41
  • 79

1 Answers1

1

You can check for change Theme there

You need change dynamic theme based on different user so post notification and apply theme what you need

// We create a model
struct Theme {
    let theme: String
    let fontColor: UIColor
    let alpha: CGFloat
}

// We need a protocol for we don't want all view controller listen theme
protocol Themeable: class {
    func listenTheme()
    func didThemeChange(theme: Theme)
}


// Global notification name
let themeableNotificationName = Notification.Name(rawValue: "ThemeableNotification")

// Our protocol extension and observer notification
extension Themeable where Self: UIViewController {
    func listenTheme() {
        NotificationCenter.default.addObserver(forName: themeableNotificationName, object: nil, queue: nil) { [weak self] notification in
            guard let theme = notification.object as? Theme else { return }
            self?.didThemeChange(theme: theme)
        }
    }

}


// Notification sender themeController
class NotifyThemeController: UIViewController {


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // Create a model and post
        NotificationCenter.default.post(name: themeableNotificationName, object: Theme(theme: "Lorem", fontColor: .red, alpha: 1.0), userInfo: nil)
    }

}

// YViewController
class YViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // We need call this method for observer
        listenTheme()
    }


}
// YViewController conforms Themeable
extension YViewController: Themeable {
    func didThemeChange(theme: Theme) {
        // TODO UI
    }

}
// ZViewController
class ZViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // We need call this method for observer
        listenTheme()
    }


}
// ZViewController conforms Themeable
extension ZViewController: Themeable {
    func didThemeChange(theme: Theme) {
        // TODO UI
    }

}

Have Fun!

Vicaren
  • 654
  • 4
  • 12