feat: dynamic theme update

This commit is contained in:
TrueZhuanjia committed 2025-09-18 16:53:17 +08:00
1 parent 1614bb0609
commit 60dacdf05f
8 files changed
+35 -40

No files matched your search

+8 -2
View File
@@ -434,8 +434,7 @@ static const float REFRESH_CYCLE = 2.0f;
[self updateTheme]; [self updateTheme];
} }
- (void)createBackgroundLayer{ - (void)updateBackgroundLayerTheme{
backgroundLayer = [CAGradientLayer layer];
UIColor *gradientColorDark = [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0]; UIColor *gradientColorDark = [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0];
UIColor *gradientColorLight = [gradientColorDark colorWithAlphaComponent:0.52]; UIColor *gradientColorLight = [gradientColorDark colorWithAlphaComponent:0.52];
CGColorRef gradientColorRef = ThemeManager.userInterfaceStyle == UIUserInterfaceStyleDark ? gradientColorDark.CGColor : gradientColorLight.CGColor; CGColorRef gradientColorRef = ThemeManager.userInterfaceStyle == UIUserInterfaceStyleDark ? gradientColorDark.CGColor : gradientColorLight.CGColor;
@@ -445,7 +444,11 @@ static const float REFRESH_CYCLE = 2.0f;
(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor clearColor].CGColor,
(__bridge id)gradientColorRef (__bridge id)gradientColorRef
]; ];
}
- (void)createBackgroundLayer{
backgroundLayer = [CAGradientLayer layer];
[self updateBackgroundLayerTheme];
backgroundLayer.locations = @[@0, @0.18, @0.5, @1]; backgroundLayer.locations = @[@0, @0.18, @0.5, @1];
backgroundLayer.startPoint = CGPointMake(0.25, 0.5); backgroundLayer.startPoint = CGPointMake(0.25, 0.5);
backgroundLayer.endPoint = CGPointMake(0.75, 0.5); backgroundLayer.endPoint = CGPointMake(0.75, 0.5);
@@ -474,7 +477,10 @@ static const float REFRESH_CYCLE = 2.0f;
_hostNameLabel.textColor = [ThemeManager textColor]; _hostNameLabel.textColor = [ThemeManager textColor];
[_appButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal]; [_appButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal];
_separatorLine.backgroundColor = [ThemeManager separatorColor]; _separatorLine.backgroundColor = [ThemeManager separatorColor];
backgroundLayer.hidden = NO; backgroundLayer.hidden = NO;
[self updateBackgroundLayerTheme];
[self updateContentsForHost:_host]; [self updateContentsForHost:_host];
} }
+2
View File
@@ -29,6 +29,8 @@
@property (nonatomic, assign) CGFloat headerViewHeight; @property (nonatomic, assign) CGFloat headerViewHeight;
@property (nonatomic, assign) CGFloat headerViewVerticalSpacing; @property (nonatomic, assign) CGFloat headerViewVerticalSpacing;
@property (nonatomic, strong) NSMutableArray<UIStackView *> *subStackViews; @property (nonatomic, strong) NSMutableArray<UIStackView *> *subStackViews;
@property (nonatomic, strong) UIImageView *iconImageView;
@property (nonatomic, strong) UIView *separatorLine;
@property (nonatomic, weak) id<MenuSectionDelegate> delegate; // Delegate property @property (nonatomic, weak) id<MenuSectionDelegate> delegate; // Delegate property
// 方法 // 方法
-2
View File
@@ -15,12 +15,10 @@
@property (nonatomic, strong) UIStackView *rootStackView; @property (nonatomic, strong) UIStackView *rootStackView;
@property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIImageView *iconImageView;
@property (nonatomic, strong) UIButton *toggleButton; @property (nonatomic, strong) UIButton *toggleButton;
@property (nonatomic, strong) UIButton *toggleArea; @property (nonatomic, strong) UIButton *toggleArea;
@property (nonatomic, strong) NSLayoutConstraint *heightConstraint; @property (nonatomic, strong) NSLayoutConstraint *heightConstraint;
@property (nonatomic, strong) UIView *headerView; @property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIView *separatorLine;
@end @end
@@ -100,10 +100,6 @@ static const CGFloat cellOffsetY = 20;
return self; return self;
} }
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)updateTheme { - (void)updateTheme {
self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; self.collectionView.backgroundColor = [ThemeManager appBackgroundColor];
for (HostCell *cell in [self.collectionView visibleCells]) { for (HostCell *cell in [self.collectionView visibleCells]) {
@@ -116,11 +112,6 @@ static const CGFloat cellOffsetY = 20;
[self.collectionView registerClass:[HostCell class] forCellWithReuseIdentifier:@"HostCell"]; [self.collectionView registerClass:[HostCell class] forCellWithReuseIdentifier:@"HostCell"];
self.collectionView.alwaysBounceVertical = NO; self.collectionView.alwaysBounceVertical = NO;
self.collectionView.showsVerticalScrollIndicator = NO; self.collectionView.showsVerticalScrollIndicator = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateTheme)
name:ThemeDidChangeNotification
object:nil];
[self updateTheme]; [self updateTheme];
} }
@@ -1548,6 +1548,7 @@ static NSMutableSet* hostList;
} }
// Called when the system's theme (light/dark mode) changes // Called when the system's theme (light/dark mode) changes
// will not be active if the app is streaming
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection]; [super traitCollectionDidChange:previousTraitCollection];
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
@@ -832,11 +832,6 @@ const int FrontViewPositionNone = 0xff;
} }
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
}
- (void)dealloc { - (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
@@ -907,6 +902,7 @@ const int FrontViewPositionNone = 0xff;
} }
if(_frontViewPosition != FrontViewPositionLeft){ if(_frontViewPosition != FrontViewPositionLeft){
[self updateTheme];
[self setupMoreButtonMenu]; [self setupMoreButtonMenu];
[self layoutSettingsView]; //注意, 该方法在菜单展开前又运行了一次, 会执行按清单隐藏stack的任务,此时直接使用.hidden = false 的方式,将stack从hiddenstacks清单中移除,导致stack保持隐藏无法恢复; [self layoutSettingsView]; //注意, 该方法在菜单展开前又运行了一次, 会执行按清单隐藏stack的任务,此时直接使用.hidden = false 的方式,将stack从hiddenstacks清单中移除,导致stack保持隐藏无法恢复;
//而此willMoveToPosition内部方法,发生在 delegate的willMoveToPosition之后(由mainFrameVC执行的委托) //而此willMoveToPosition内部方法,发生在 delegate的willMoveToPosition之后(由mainFrameVC执行的委托)
@@ -1,5 +1,5 @@
// //
// SettingsViewControllerSettingsViewController.m // SettingsViewController.m
// Moonlight // Moonlight
// //
// Created by Diego Waxemberg on 10/27/14. // Created by Diego Waxemberg on 10/27/14.
@@ -354,6 +354,11 @@ BOOL isCustomResolution(int resolutionSelected) {
name:UIDeviceOrientationDidChangeNotification name:UIDeviceOrientationDidChangeNotification
object:nil]; object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateTheme)
name:ThemeDidChangeNotification
object:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if(self.mainFrameViewController.settingsExpandedInStreamView){ if(self.mainFrameViewController.settingsExpandedInStreamView){
NSInteger responseCode = [self.mainFrameViewController requestForBitrate:self->_bitrate]; NSInteger responseCode = [self.mainFrameViewController requestForBitrate:self->_bitrate];
@@ -405,7 +410,6 @@ BOOL isCustomResolution(int resolutionSelected) {
return [self isIPhone] ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad; return [self isIPhone] ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad;
} }
- (void)initParentStack{ - (void)initParentStack{
self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic; self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
// 可选:确保 scrollView 开启垂直滚动 // 可选:确保 scrollView 开启垂直滚动
@@ -1358,16 +1362,7 @@ BOOL isCustomResolution(int resolutionSelected) {
*/ */
} }
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad { - (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateTheme)
name:ThemeDidChangeNotification
object:nil];
settingStackWillBeRelocatedToLowestPosition = false; settingStackWillBeRelocatedToLowestPosition = false;
hiddenStacks = [[NSMutableSet alloc] init]; hiddenStacks = [[NSMutableSet alloc] init];
@@ -2325,6 +2320,7 @@ BOOL isCustomResolution(int resolutionSelected) {
if(label.accessibilityIdentifier != nil) break; if(label.accessibilityIdentifier != nil) break;
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
label.layer.filters = nil; label.layer.filters = nil;
label.textColor = [UIColor clearColor];
label.textColor = [ThemeManager textColor]; label.textColor = [ThemeManager textColor];
} else { } else {
UIView *view = label; UIView *view = label;
@@ -2348,6 +2344,7 @@ BOOL isCustomResolution(int resolutionSelected) {
if ([subview isKindOfClass:[UISegmentedControl class]]) { if ([subview isKindOfClass:[UISegmentedControl class]]) {
UISegmentedControl *selector = (UISegmentedControl *)subview; UISegmentedControl *selector = (UISegmentedControl *)subview;
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
selector.selectedSegmentTintColor = [UIColor clearColor];
selector.selectedSegmentTintColor = [ThemeManager appSecondaryColor]; selector.selectedSegmentTintColor = [ThemeManager appSecondaryColor];
} else { } else {
selector.tintColor = [ThemeManager appSecondaryColor]; selector.tintColor = [ThemeManager appSecondaryColor];
@@ -2361,16 +2358,30 @@ BOOL isCustomResolution(int resolutionSelected) {
for (UIView *subview in view.subviews) { for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UISlider class]]) { if ([subview isKindOfClass:[UISlider class]]) {
UISlider *slider = (UISlider *)subview; UISlider *slider = (UISlider *)subview;
slider.tintColor = [UIColor clearColor];
slider.tintColor = [ThemeManager appSecondaryColor]; slider.tintColor = [ThemeManager appSecondaryColor];
} }
[self updateThemeForSliders:subview]; [self updateThemeForSliders:subview];
} }
} }
- (void)updateThemeForMenuSections:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[MenuSectionView class]]) {
MenuSectionView *section = (MenuSectionView *)subview;
section.iconImageView.tintColor = [UIColor clearColor];
section.iconImageView.tintColor = [ThemeManager textColor];
section.separatorLine.backgroundColor = [UIColor clearColor];
section.separatorLine.backgroundColor = [ThemeManager separatorColor];
}
[self updateThemeForMenuSections:subview];
}
}
- (void)updateTheme{ - (void)updateTheme{
self.view.backgroundColor = [UIColor clearColor];
self.view.backgroundColor = [ThemeManager appBackgroundColor]; self.view.backgroundColor = [ThemeManager appBackgroundColor];
[self updateThemeForMenuSections:self.view];
[self updateThemeForLabels:self.view]; [self updateThemeForLabels:self.view];
[self updateThemeForSelectors:self.view]; [self updateThemeForSelectors:self.view];
[self updateThemeForSliders:self.view]; [self updateThemeForSliders:self.view];
@@ -580,11 +580,6 @@
_spinner.color = [ThemeManager textColor]; _spinner.color = [ThemeManager textColor];
} }
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad - (void)viewDidLoad
{ {
viewJustLoaded = true; viewJustLoaded = true;
@@ -595,11 +590,6 @@
[UIApplication sharedApplication].idleTimerDisabled = YES; [UIApplication sharedApplication].idleTimerDisabled = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateTheme)
name:@"ThemeDidChangeNotification"
object:nil];
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here. _settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
_stageLabel = [[UILabel alloc] init]; _stageLabel = [[UILabel alloc] init];