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

Move fluentTheme from window to view #1219

Merged
merged 3 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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