Skip to content

Theme management solution for Swift with UIKit.

License

Notifications You must be signed in to change notification settings

igniti0n/Themer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

T̼̼̖̾͟͞h̨͚͚͖ͯ̒̄͗͞ḛ̡̰̳͓̥ͬ͋ͪͧm̰̰̹͚̙̂ͦ͗͠ḛ̡̰̳͓̥ͬ͋ͪͧṛ̣̬̫̍͌ͩ͟

Version License Platform

Themer enables you to switch between light, dark, and system default theme modes, gives you default themed classes of each view, and allows you to define all assets (color, border color, font, border width...) for them, as well as giving you the option to make your own custom themed views and their assets. Moves code from your view by defining their looks from one place and makes changes to styling easy.

Installation

Themer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Themer'

Features

  • switching between light / dark / system default
  • animated theme changes
  • listening to theme changes
  • themed views, not just colors and fonts
  • adding multiple custom themed views

How to use it

Themer is straight forward to use, setup your themes and apply whatever theme you want!

Setup a theme

Define your themes by inheriting from 'ApplicationTheme'. It enables you to define many different assets for your themed views in that theme.

class DarkTheme: ApplicationTheme {
    var theme: Theme = Theme(
        assets: ThemeAssets(
            labelAssets: LabelAssets(
                color: .orange,
                font: .systemFont(ofSize: 48),
                backgroundColor: .white
            ),
            buttonAssets: ButtonAssets(
                buttonColor: .black,
                titleColor: .white,
                font: .systemFont(ofSize: 28),
                cornerRadius: 80,
                borderColor: .systemPurple
            ),
            imageViewAssets: ImageViewAssets(
                tintColor: .systemRed
            )))
}

class LightTheme: ApplicationTheme {
            var theme: Theme = DarkTheme().theme.copyWith(ThemeAssets(
                labelAssets: LabelAssets(
                    color: .blue
                )))

In your app, as soon as possible, setup your theme. By default, when you first start your app, theme will be whatever the system default is.

        Themer.shared.setup(lightTheme: LightTheme(), darkTheme: DarkTheme())

Anywhere in your application, you can apply a theme and your app theme will change. You can also use animations when applying a theme.

        // Instant theme switch
        Themer.shared.apply(.dark)
        
        // Fancy theme switch
        Themer.shared.apply(.systemDefault, withAnimation: ThemeAnimationSettings(duration: 0.4, delay: 0, animationOptions: .transitionFlipFromTop))

Use themed views in your view

In your theme, all assets correspond to their themed versions. So, 'ButtonAssets' define what 'ThemedButton' looks like.

Instead

    let button = UIButton()

Use

    let button = ThemedButton()

'ThemedButton' is just like a normal UIButton, but all the properties from 'ButtonAssets' will be applied to it. So, you don't need any styling for it anywhere.

NavigationBarAssets

NavigationBarAssets are initialized differently than other assets. All three appearance's need to be accounted for: standard, compact and scroll edge. You are given a closure for each one, with a paramater being an instance of the 'UINavigationBarAppearance' that you can change properties on for each appearance, everything else is the same.

            navigationBarAssets: NavigationBarAssets(standardApprance: { appearance in
                appearance.backgroundColor = .blue
                appearance.titleTextAttributes = [.font : UIFont.systemFont(ofSize: 28), .foregroundColor : UIColor.purple]
            }, scrollEdgeApperance: { appearance in
                appearance.titleTextAttributes = [.font : UIFont.systemFont(ofSize: 24), .foregroundColor : UIColor.yellow]
            }, compactApperance: { appearance in
                appearance.titleTextAttributes = [.font : UIFont.systemFont(ofSize: 20), .foregroundColor : UIColor.blue]
            }

By default, standard appearance is applied on all appearances, whatever you do in scroll edge or compact appearance closures, will be added/changed based on the standard appearance. Note that on, for example, iOS 14 and 15, appearances behave a bit differently and you are free to check the current iOS version and set different values in each closure based on that. For example, I have found that in some situations scroll edge appearance is being applied on iOS 15, wherein iOS 14 standard appearance was applied.

Listen to theme changes

Anywhere in your application, you can listen to theme changes using 'NotificationCenter'

        let nc = NotificationCenter.default
        nc.addObserver(self, selector: #selector(onThemeChanged), name: Themer.notificationName, object: nil)

Custom themed views

Out of the box, you get a themed view like ThemedButton, ThemedNavigationBar, ThemedLabel... But, what if you want 2 or 3 different styles of buttons in a light and dark theme? No problem, just create a custom-themed view and attach assets to them.

Create a themed view, by extending one of the 'Themable' prefixed protocols.

        class CustomThemedButton: ThemableButton {}

Add assets for that custom themed view to light, dark or both themes.

        Themer.shared.addCustomAssets(to: .both, asset: ButtonAssets<CustomThemedButton>(buttonColor: .systemBrown))

Use it!

    let button = CustomThemedButton()

Author

igniti0n, [email protected]

License

Themer is available under the MIT license. See the LICENSE file for more info.

About

Theme management solution for Swift with UIKit.

Resources

License

Stars

Watchers

Forks

Packages

No packages published