Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing Theming to Material #1115

Merged
merged 36 commits into from
Oct 16, 2018
Merged

Introducing Theming to Material #1115

merged 36 commits into from
Oct 16, 2018

Conversation

OrkhanAlikhanov
Copy link
Contributor

@OrkhanAlikhanov OrkhanAlikhanov commented Jul 17, 2018

General

Both views and viewControllers can be themed in Material:

  • Views:

    • TextField
    • RaisedButton
  • ViewControllers:

    • BottomNavigationController
    • StatusBarController

How to use

Setting Theme for the app.

let appTheme = Theme()
appTheme.primary = Color.green.base
Theme.apply(theme: appTheme)

Getting current Theme object.

let currentTheme = Theme.current // current theme of the app

Material has 2 themes built in. Light and dark:

Theme.apply(theme: .dark) // Set dark theme for the app
Theme.apply(theme: .light) // Set light theme for the app (default)

Created Themeable views will be immediately themed with the Theme.current.

Theme.apply(theme: .light)
let lightThemedButton = RaisedButton()

Theme.apply(theme: .dark)
let darkThemedButton = RaisedButton()

Disabling theming

Theming may (sometimes) override previously set colors. In such cases, you can use isThemingEnabled to disable theming for the a view (including its subviews).

let button = IconButton()
button.isThemingEnabled = false
button.tintColor = Color.red
navigationItem.rightViews = [button] // would override tintColor if theming was not disabled 

More

Setting theme for the a specific view or viewController hierarchy:

// Views
myView.apply(theme: .dark) // Apply dark theme to myView (ignores isThemingEnabled)
Theme.apply(theme: .dark, to: myView) // Apply dark theme to myView and its subviews (respects isThemingEnabled)

// ViewControllers
viewController.apply(theme: .dark) // Apply dark theme to viewController (ignores isThemingEnabled)
Theme.apply(theme: .dark, to: viewController) // Apply dark theme to viewController (including views) and its children (respects isThemingEnabled)

Sample

Here is sample app to test theming out. Button.zip

Double tap on background to change theme.

@OrkhanAlikhanov OrkhanAlikhanov changed the title Introducing Theming to Material [WIP] Introducing Theming to Material Jul 17, 2018
@daniel-jonathan daniel-jonathan self-requested a review July 17, 2018 20:28
@daniel-jonathan
Copy link
Member

@OrkhanAlikhanov Is this still WIP?

@OrkhanAlikhanov
Copy link
Contributor Author

@DanielDahan Let's close this and reopen when I start working on this feature

@OrkhanAlikhanov OrkhanAlikhanov changed the base branch from master to development October 4, 2018 21:07
@OrkhanAlikhanov OrkhanAlikhanov changed the title [WIP] Introducing Theming to Material Introducing Theming to Material Oct 11, 2018
Copy link
Member

@daniel-jonathan daniel-jonathan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this!

@daniel-jonathan daniel-jonathan merged commit 77a779d into CosmicMind:development Oct 16, 2018
@muzoman
Copy link

muzoman commented Oct 18, 2018

These theme changes have completely broken my UI. Is there a way to globally disable use of themes?

@OrkhanAlikhanov
Copy link
Contributor Author

Hey! Can you share detailed information how it breaks your UI? which parts? I assume it breaks the NavigationBar, in this case you can disable it like this:

(navigationController.navigationBar as! NavigationBar).isThemingEnabled = false

@muzoman
Copy link

muzoman commented Oct 18, 2018

From a coding perspective I now have to litter my code with ".isThemingEnabled = false" on buttons, toolbars etc. Or I've got to subclass everything to set this to false and then change all my code to use the subclasses.

You're right - the first thing I've tried to fix that is now broken is the NavigationBar - this was respecting the background color I'd set, but now does not. I set the isThemingEnabled flag as you described above and this has no effect. I've got a slightly complicated App top level structure, perhaps there's some other class where I need to set this flag to off?

`let homeViewController = HomeViewController()

        let navController = AppNavigationController(rootViewController: homeViewController)
        let sideMenuViewController = SideMenuViewController(rootVCKey: "HomeViewController", rootVC: homeViewController)
        let navigationDrawerController = AppNavigationDrawerController(rootViewController:  navController,
                                                                       leftViewController:  sideMenuViewController,
                                                                       rightViewController: nil)

`
AppNavigationController is my subclass of navigationController where I'm setting the Theming flag to false.
img_dcfae0e0ec7f-1
In the above image the nav bar should be black.

@OrkhanAlikhanov
Copy link
Contributor Author

Theming is applied for UIViews when they are created, and for UIViewControllers in viewDidLoad(). This allows us to override theme in prepare (after calling super.prepare) or after creating the view.

There are only two exceptions where theming is re-applied. One is UINavigationItem which is themed when it gets laid out, and the other one is Toolbar, which is re-themed when rightViews, leftViews or centerViews are changed. Both respects isThemingEnabled.

To disable theming for the entire app, you can make isThemingEnabled to return always false for now. Just replace line 178 with return false

var isThemingEnabled: Bool {
get {
return AssociatedObject.get(base: self, key: &IsThemingEnabledKey) {
true
}
}

@muzoman
Copy link

muzoman commented Oct 18, 2018

Thanks for that information. I did as you suggested above but this surprisingly didn't restore everything to before. Now instead of blue my AppBar is white, so some part of the new code is not behaving as it did when isThemingEnabled is false.

I'll continue to sprinkle my code with flags to try to get theming to be disabled.

@daniel-jonathan
Copy link
Member

@muzoman If would like to join our #opensource Slack channel, we can discuss scenarios of how to better the theming feature. If you are interested, please send your email to [email protected].

@MuhammadNayabButt
Copy link

@muzoman did you get any solution. I tried
(navigationController.navigationBar as! NavigationBar).isThemingEnabled = false but it did not work in one view controllers. I have 4 controllers in Tabbar and one of them is showing no change at all. @DanielDahan
I have done Theme.isEnabled = false as well. Some of the controllers blinks(first theme is applied) but one controllers navigation bar stays black.

@OrkhanAlikhanov
Copy link
Contributor Author

@MuhammadNayabButt Can you send an example project replicating the issue? You can send it to [email protected]

@muzoman
Copy link

muzoman commented Nov 14, 2018

@muzoman did you get any solution. I tried
(navigationController.navigationBar as! NavigationBar).isThemingEnabled = false but it did not work in one view controllers. I have 4 controllers in Tabbar and one of them is showing no change at all. @DanielDahan
I have done Theme.isEnabled = false as well. Some of the controllers blinks(first theme is applied) but one controllers navigation bar stays black.

@MuhammadNayabButt Yes, everything is working as expected for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

4 participants