【问题标题】:How to dynamically switch UI theme based on different user types in iOSiOS中如何根据不同用户类型动态切换UI主题
【发布时间】:2019-07-24 08:23:32
【问题描述】:

在我的应用程序中,我有一个场景需要根据用户类型切换 UI 主题设计。例如:在我的 Type1 用户流中,它类似于 Registration Screen -> HomePage Screen,而在我的 Type 2 用户中,它应该类似于 Registration Screen-> Contact Screen -> Home Page Screen。并且对于 Type 2 用户来说,UI 设计和主题是不同的。为了实现这一点,下面是我当前实现的示例代码流。

RegistrationViewController

(此视图可供两个用户使用,但 UI 主题不同,如导航栏颜色、背景颜色、按钮颜色、字体、图像等)

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 (此视图仅适用于 type1 用户)

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


private func setupViews(){

        //Setupviews 

}

 @IBAction func continueAction(_ sender: Any) {

            gotToHomeView()

}

HomeViewController (此视图可供两个用户使用,但 UI 主题与注册中提到的不同)

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



private func setupViews(){

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

}

这工作正常,但这里的问题是现在我在实用程序中定义了一个isUserType,并且它不是完全可扩展的。对于每个流程和 UI 更改,我需要根据此参数设置一个 if-else 条件。因此,现在如果我有另一个需要在未来添加的用户类型,我将再次需要另一个 if-else 语句并基于此切换 UI 和流程。

有没有更好的方法来解决这个问题?

【问题讨论】:

  • 你的主题定义应该基于 userType/category

标签: ios swift design-patterns swift4.2 xcode10.1


【解决方案1】:

您可以检查更改主题 there

您需要根据不同的用户更改动态主题,以便发布通知并应用您需要的主题

// 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
    }

}

玩得开心!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2018-07-30
    相关资源
    最近更新 更多