When I first started working on TenPair I knew that I should also do something about game UI themes support. But I did not have clear idea how to approach it at that time. This resulted in following monstrosity:
background.fillColor = TenPairTheme.currentTheme.consumedTileColor!
Well… At least colors were not hardcoded… But it wasn’t also much better. Dirty singletons everywhere… And I never got to how theme changes should be handled.
With the latest update to TenPair I wished to add at least one additional color theme. And as it was period for rethinking SpriteKitUI, it was time to address theming.
UIKit has a nice way to set elements appearance app wide. For example setting navigation bar color:
UINavigationBar.appearance().barTintColor = .blue
UINavigationBar.appearance().tintColor = .white
Set once and forget. I wished to use similar pattern.
First step for identifying elements that can be themed was to introduce theming protocol
public protocol Themed {
static func appearance() -> Appearance
func set(color: SKColor, for attribute: Appearance.Attribute)
func set(value: String, for attribute: Appearance.Attribute)
}
Appearance defines a bag of properties for every UI element based on full class name. Appearance.Attribute is user defined property key that will be used when theme is applied.
Sample usage for defining app wide View colors:
View.appearance().set(color: SKColor.white, for: .background)
View.appearance().set(color: lightBlue, for: .foreground)
During theming phase elements will receive defined properties with attribute keys:
open class View: SKSpriteNode, Themed
open func set(color: SKColor, for attribute: Appearance.Attribute) {
switch attribute {
case Appearance.Attribute.background:
backgroundColor = color
default:
break // no op
}
}
}
When ever colors need to be changed, you will need to perform appearance calls with new values and call applyTheme() on game object
Overall this allowed clear separation of theme definition form game logic and UI. If I only had more theme ideas…
Tags: ios, spritekit