Skip to content

Commit

Permalink
Move fluentTheme from window to view (#1219)
Browse files Browse the repository at this point in the history
* Move `fluentTheme` from window to view

* Add logic to only refresh if view is a descendent of the newly themed view
  • Loading branch information
mischreiber committed Sep 7, 2022
1 parent 1ea24c2 commit 9344d17
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 28 deletions.
13 changes: 4 additions & 9 deletions ios/FluentUI/Core/ControlHostingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,19 @@ open class ControlHostingView: UIView {
}

@objc private func themeDidChange(_ notification: Notification) {
guard let themeView = notification.object as? UIView, self.isDescendant(of: themeView) else {
return
}
updateRootView()
}

private func updateRootView() {
self.hostingController.rootView = tokenizedView
}

private var currentFluentTheme: FluentTheme {
if let windowFluentTheme = self.window?.fluentTheme {
return windowFluentTheme
} else {
return FluentThemeKey.defaultValue
}
}

private var tokenizedView: AnyView {
return AnyView(controlView
.fluentTheme(currentFluentTheme)
.fluentTheme(fluentTheme)
.onAppear { [weak self] in
// We don't usually have a window at construction time, so fetch our
// custom theme during `onAppear`
Expand Down
27 changes: 16 additions & 11 deletions ios/FluentUI/Core/Theme/FluentTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,27 @@ public extension Notification.Name {
static let didChangeTheme = Notification.Name("FluentUI.stylesheet.theme")
}

extension UIWindow: FluentThemeable {
@objc extension UIView: FluentThemeable {
private struct Keys {
static var fluentTheme: String = "fluentTheme_key"
static var cachedFluentTheme: String = "cachedFluentTheme_key"
}

/// The custom `FluentTheme` to apply to this window.
public override var fluentTheme: FluentTheme {
/// The custom `FluentTheme` to apply to this view.
public var fluentTheme: FluentTheme {
get {
return objc_getAssociatedObject(self, &Keys.fluentTheme) as? FluentTheme ?? FluentThemeKey.defaultValue
var optionalView: UIView? = self
while let view = optionalView {
// If we successfully find a theme, return it.
if let theme = objc_getAssociatedObject(view, &Keys.fluentTheme) as? FluentTheme {
return theme
} else {
optionalView = view.superview
}
}

// No custom themes anywhere, so return the default theme
return FluentTheme.shared
}
set {
objc_setAssociatedObject(self, &Keys.fluentTheme, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
Expand All @@ -74,13 +86,6 @@ extension UIWindow: FluentThemeable {
}
}

@objc public extension UIView {
/// Returns the current view's window's `FluentTheme`, or the default `FluentTheme` if no window yet exists.
var fluentTheme: FluentTheme {
return self.window?.fluentTheme ?? FluentThemeKey.defaultValue
}
}

// MARK: - Environment

public extension View {
Expand Down
4 changes: 2 additions & 2 deletions ios/FluentUI/Other Cells/ActionsCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ open class ActionsCell: UITableViewCell, TokenizedControlInternal {
var tokenSetSink: AnyCancellable?

@objc private func themeDidChange(_ notification: Notification) {
guard let window = window, window.isEqual(notification.object) else {
guard let themeView = notification.object as? UIView, self.isDescendant(of: themeView) else {
return
}
tokenSet.update(window.fluentTheme)
tokenSet.update(fluentTheme)
updateAppearance()
}

Expand Down
4 changes: 2 additions & 2 deletions ios/FluentUI/Other Cells/ActivityIndicatorCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ open class ActivityIndicatorCell: UITableViewCell, TokenizedControlInternal {
var tokenSetSink: AnyCancellable?

@objc private func themeDidChange(_ notification: Notification) {
guard let window = window, window.isEqual(notification.object) else {
guard let themeView = notification.object as? UIView, self.isDescendant(of: themeView) else {
return
}
tokenSet.update(window.fluentTheme)
tokenSet.update(fluentTheme)
updateAppearance()
}

Expand Down
4 changes: 2 additions & 2 deletions ios/FluentUI/Other Cells/CenteredLabelCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ open class CenteredLabelCell: UITableViewCell, TokenizedControlInternal {
var tokenSetSink: AnyCancellable?

@objc private func themeDidChange(_ notification: Notification) {
guard let window = window, window.isEqual(notification.object) else {
guard let themeView = notification.object as? UIView, self.isDescendant(of: themeView) else {
return
}
tokenSet.update(window.fluentTheme)
tokenSet.update(fluentTheme)
updateAppearance()
}

Expand Down
4 changes: 2 additions & 2 deletions ios/FluentUI/Table View/TableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ open class TableViewCell: UITableViewCell, TokenizedControlInternal {
var tokenSetSink: AnyCancellable?

@objc func themeDidChange(_ notification: Notification) {
guard let window = window, window.isEqual(notification.object) else {
guard let themeView = notification.object as? UIView, self.isDescendant(of: themeView) else {
return
}
tokenSet.update(window.fluentTheme)
tokenSet.update(fluentTheme)
updateAppearance()
}

Expand Down

0 comments on commit 9344d17

Please sign in to comment.