From 4b56a44a47fba98f9a82a0df1d49a802116428ec Mon Sep 17 00:00:00 2001 From: True Zhuanjia Date: Fri, 6 Mar 2026 17:29:38 +0800 Subject: [PATCH] UI improvements --- VoidLink.xcodeproj/project.pbxproj | 10 +- VoidLink/HostCardView.m | 4 +- VoidLink/MenuSectionView.h | 5 +- VoidLink/MenuSectionView.m | 54 ++-- VoidLink/ThemeManager.h | 27 -- VoidLink/ThemeManager.m | 152 ---------- VoidLink/ThemeManager.swift | 273 ++++++++++++++++++ VoidLink/UIAppView.m | 2 +- .../LayoutOnScreenControlsViewController.m | 2 +- .../HostCollectionViewController.m | 4 +- .../ViewControllers/MainFrameViewController.m | 17 +- .../ViewControllers/SWRevealViewController.m | 22 +- .../ViewControllers/SettingsViewController.m | 32 +- .../StreamFrameViewController.m | 4 +- VoidLink/VoidLink-Bridging-Header.h | 1 - 15 files changed, 354 insertions(+), 255 deletions(-) delete mode 100644 VoidLink/ThemeManager.h delete mode 100644 VoidLink/ThemeManager.m create mode 100644 VoidLink/ThemeManager.swift diff --git a/VoidLink.xcodeproj/project.pbxproj b/VoidLink.xcodeproj/project.pbxproj index dcf7bf3c..771315f8 100644 --- a/VoidLink.xcodeproj/project.pbxproj +++ b/VoidLink.xcodeproj/project.pbxproj @@ -34,9 +34,9 @@ 18D43D7F2F050240008C326F /* PressureCurve.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D43D7E2F050240008C326F /* PressureCurve.swift */; }; 18E4BCEA2E891895000A8657 /* MotionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E4BCE92E891895000A8657 /* MotionHandler.swift */; }; 18FCADAF2ECAC23200787A96 /* PencilHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FCADAE2ECAC23200787A96 /* PencilHandler.swift */; }; + 2A7113FD2F5A6C65001D852D /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7113FC2F5A6C65001D852D /* ThemeManager.swift */; }; 2AC1E3832F507D80004F76C0 /* GenericUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AC1E3822F507D80004F76C0 /* GenericUtils.swift */; }; 840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; }; - 841BAC922DE35D6B00DA639E /* ThemeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 841BAC912DE35D6B00DA639E /* ThemeManager.m */; }; 84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */; }; 84351B0E2C29ACCB00A77989 /* LayoutOnScreenControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */; }; 84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B092C29ACCA00A77989 /* OnScreenButtonState.m */; }; @@ -199,12 +199,11 @@ 18D43D7E2F050240008C326F /* PressureCurve.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PressureCurve.swift; sourceTree = ""; }; 18E4BCE92E891895000A8657 /* MotionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MotionHandler.swift; sourceTree = ""; }; 18FCADAE2ECAC23200787A96 /* PencilHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PencilHandler.swift; sourceTree = ""; }; + 2A7113FC2F5A6C65001D852D /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = ""; }; 2AC1E3822F507D80004F76C0 /* GenericUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericUtils.swift; sourceTree = ""; }; 693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = ""; }; 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = ""; }; - 841BAC8F2DE35BEC00DA639E /* ThemeManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThemeManager.h; sourceTree = ""; }; - 841BAC912DE35D6B00DA639E /* ThemeManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThemeManager.m; sourceTree = ""; }; 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenWidgetView.swift; sourceTree = ""; }; 84351B062C29ACCA00A77989 /* OnScreenButtonState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenButtonState.h; sourceTree = ""; }; 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LayoutOnScreenControls.m; sourceTree = ""; }; @@ -661,8 +660,7 @@ FB290D0319B2C406004C83CF /* AppDelegate.m */, 848F45682DDCD0D600581E36 /* HostCardView.h */, 848F45692DDCD12500581E36 /* HostCardView.m */, - 841BAC8F2DE35BEC00DA639E /* ThemeManager.h */, - 841BAC912DE35D6B00DA639E /* ThemeManager.m */, + 2A7113FC2F5A6C65001D852D /* ThemeManager.swift */, 847D2FD82DDA00C800937A62 /* MenuSectionView.h */, 847D2FDA2DDA015F00937A62 /* MenuSectionView.m */, FBDE86E419F82297001C18A8 /* UIAppView.h */, @@ -1099,6 +1097,7 @@ 1817B61E2E6FD04D000D938D /* SafeTimer.swift in Sources */, FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */, 843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */, + 2A7113FD2F5A6C65001D852D /* ThemeManager.swift in Sources */, FB89462C19F646E200339C8A /* HttpManager.m in Sources */, FB89462D19F646E200339C8A /* MDNSManager.m in Sources */, 84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */, @@ -1108,7 +1107,6 @@ FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */, 18D43D7F2F050240008C326F /* PressureCurve.swift in Sources */, 180E6E372E93BFDB0067C73A /* AlertControllerUtil.swift in Sources */, - 841BAC922DE35D6B00DA639E /* ThemeManager.m in Sources */, 98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */, FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */, FBD1C8E21A8AD71400C6703C /* Logger.m in Sources */, diff --git a/VoidLink/HostCardView.m b/VoidLink/HostCardView.m index d539d511..f02ba211 100644 --- a/VoidLink/HostCardView.m +++ b/VoidLink/HostCardView.m @@ -8,7 +8,7 @@ #import "HostCardView.h" #import "LocalizationHelper.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" #import "FixedTintImageView.h" @@ -574,7 +574,7 @@ static const float REFRESH_CYCLE = 2.0f; case StateOffline: [_hostSpinner stopAnimating]; // _iconBackgroundView.backgroundColor = _userIterfaceStyle == UIUserInterfaceStyleDark ? [UIColor appBackgroundColorDark] : [UIColor appBackgroundColorLight]; - _iconBackgroundView.backgroundColor = [ThemeManager appBackgroundColor]; + _iconBackgroundView.backgroundColor = [ThemeManager offlineHostIconBackgroundColor]; _statusLabel.textColor = [ThemeManager textColorGray]; _statusLabel.text = [LocalizationHelper localizedStringForKey: @"Offline"]; _statusIcon.tintColor = [ThemeManager textColorGray]; diff --git a/VoidLink/MenuSectionView.h b/VoidLink/MenuSectionView.h index 16f12728..ace57b01 100644 --- a/VoidLink/MenuSectionView.h +++ b/VoidLink/MenuSectionView.h @@ -25,6 +25,7 @@ @property (nonatomic, strong) UIStackView *rootStackView; @property (nonatomic, assign) CGFloat leadingTrailingPadding; @property (nonatomic, assign) CGFloat separatorLinePadding; +@property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, copy) NSString *sectionTitle; @property (nonatomic, copy) NSString *identifier; @property (nonatomic, assign) BOOL isExpanded; @@ -40,8 +41,8 @@ @property (nonatomic, weak) id delegate; // Delegate property // 方法 -- (void)setSectionWithIcon:(UIImage *)icon andSize:(CGFloat)size; -- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size weight:(UIImageSymbolWeight)weight API_AVAILABLE(ios(13.0)); +- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size sizeConstraint:(CGFloat)constant; +- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size weight:(UIImageSymbolWeight)weight sizeConstraint:(CGFloat)constant API_AVAILABLE(ios(13.0)); - (void)addSubStackView:(UIStackView *)stackView; - (void)addToParentStack:(UIStackView *)parentStack; - (void)removeSubStackView:(UIStackView *)stackView; diff --git a/VoidLink/MenuSectionView.m b/VoidLink/MenuSectionView.m index f7e380ba..11a6bfe5 100644 --- a/VoidLink/MenuSectionView.m +++ b/VoidLink/MenuSectionView.m @@ -8,12 +8,11 @@ // MenuSectionView.m #import "MenuSectionView.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" @interface MenuSectionView () -@property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UIButton *toggleButton; @property (nonatomic, strong) UIButton *toggleArea; @property (nonatomic, strong) NSLayoutConstraint *heightConstraint; @@ -52,7 +51,7 @@ static BOOL overridePersistedFoldState = YES; - (void)commonInit { // 默认值 - _leadingTrailingPadding = 0; + _leadingTrailingPadding = 5; _separatorLinePadding = 40; _sectionTitle = @"Section"; _isExpanded = YES; @@ -83,7 +82,8 @@ static BOOL overridePersistedFoldState = YES; // 标题标签 _titleLabel = [[UILabel alloc] init]; _titleLabel.text = _sectionTitle; - _titleLabel.font = [UIFont systemFontOfSize:23 weight:UIFontWeightMedium]; + _titleLabel.accessibilityIdentifier = @"menuSectionTitleLabel"; + _titleLabel.font = [UIFont systemFontOfSize:19 weight:UIFontWeightSemibold]; _titleLabel.textColor = [ThemeManager textColor]; _titleLabel.textAlignment = NSTextAlignmentLeft; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; @@ -94,7 +94,7 @@ static BOOL overridePersistedFoldState = YES; _toggleArea = [UIButton buttonWithType:UIButtonTypeSystem]; if (@available(iOS 13.0, *)) { UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:_headerViewHeight*0.31 weight:UIImageSymbolWeightBold]; - [_toggleButton setImage:[UIImage systemImageNamed:@"chevron.left" withConfiguration:config] forState:UIControlStateNormal]; + [_toggleButton setImage:[UIImage systemImageNamed:@"chevron.right" withConfiguration:config] forState:UIControlStateNormal]; } else { // [_toggleButton setTitle:@"<" forState:UIControlStateNormal]; } @@ -142,20 +142,11 @@ static BOOL overridePersistedFoldState = YES; [_headerView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor], [_headerView.heightAnchor constraintEqualToConstant:_headerViewHeight] ]]; - - // 图标约束 - [NSLayoutConstraint activateConstraints:@[ - [_iconImageView.centerXAnchor constraintEqualToAnchor:_headerView.leadingAnchor constant:_leadingTrailingPadding+_headerViewHeight/2-3], - [_iconImageView.centerYAnchor constraintEqualToAnchor:_headerView.centerYAnchor], - // [_iconImageView.topAnchor constraintEqualToAnchor:_headerView.topAnchor], - [_iconImageView.widthAnchor constraintEqualToConstant:_headerViewHeight-6], - //[_iconImageView.heightAnchor constraintEqualToConstant:_headerViewHeight-6] - ]]; - + // 标题约束 if(@available(iOS 13.0, *)){ [NSLayoutConstraint activateConstraints:@[ - [_titleLabel.leadingAnchor constraintEqualToAnchor:_iconImageView.trailingAnchor constant:8], + [_titleLabel.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:39], [_titleLabel.centerYAnchor constraintEqualToAnchor:_headerView.centerYAnchor], [_titleLabel.trailingAnchor constraintEqualToAnchor:_toggleButton.leadingAnchor constant:-8] ]]; @@ -179,7 +170,7 @@ static BOOL overridePersistedFoldState = YES; [_toggleArea.centerYAnchor constraintEqualToAnchor:_headerView.centerYAnchor], [_toggleArea.trailingAnchor constraintEqualToAnchor:_toggleButton.leadingAnchor], //[_toggleArea.widthAnchor constraintEqualToConstant:_headerViewHeight], - [_toggleArea.heightAnchor constraintEqualToConstant:_headerViewHeight] + [_toggleArea.heightAnchor constraintEqualToConstant:_headerViewHeight+25] ]]; [self layoutIfNeeded]; @@ -198,9 +189,9 @@ static BOOL overridePersistedFoldState = YES; //[_separatorLine.leadingAnchor constraintEqualToAnchor:self.leadingAnchor], //[_separatorLine.trailingAnchor constraintEqualToAnchor:self.trailingAnchor], [_separatorLine.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], - [_separatorLine.widthAnchor constraintEqualToConstant:1000], // //mark: settingMenuLayout + [_separatorLine.widthAnchor constraintEqualToAnchor:self.widthAnchor constant:-5], // //mark: settingMenuLayout [_separatorLine.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], - [_separatorLine.heightAnchor constraintEqualToConstant:2] + [_separatorLine.heightAnchor constraintEqualToConstant:0.7] ]]; [NSLayoutConstraint activateConstraints:@[ @@ -211,7 +202,7 @@ static BOOL overridePersistedFoldState = YES; #pragma mark - Public Methods -- (void)setSectionWithIcon:(UIImage *)icon andSize:(CGFloat)size{ +- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size sizeConstraint:(CGFloat)constant{ if (@available(iOS 13.0, *)) { UIImageSymbolConfiguration *config; if(icon.isSymbolImage) config = [UIImageSymbolConfiguration configurationWithPointSize:size weight:UIImageSymbolWeightBold]; @@ -225,10 +216,19 @@ static BOOL overridePersistedFoldState = YES; } _iconImageView.tintColor = [ThemeManager textColor]; _iconImageView.hidden = (icon == nil); + + // 图标约束 + [NSLayoutConstraint activateConstraints:@[ + [_iconImageView.centerXAnchor constraintEqualToAnchor:_headerView.leadingAnchor constant:_leadingTrailingPadding+_headerViewHeight/2-3], + [_iconImageView.centerYAnchor constraintEqualToAnchor:_headerView.centerYAnchor constant:-0.5], + [_iconImageView.widthAnchor constraintEqualToConstant:_headerViewHeight+constant], + [_iconImageView.heightAnchor constraintEqualToConstant:_headerViewHeight+constant] + ]]; + [self updateLayout]; } -- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size weight:(UIImageSymbolWeight)weight API_AVAILABLE(ios(13.0)){ +- (void)setSectionWithIcon:(UIImage *)icon size:(CGFloat)size weight:(UIImageSymbolWeight)weight sizeConstraint:(CGFloat)constant API_AVAILABLE(ios(13.0)){ if (@available(iOS 13.0, *)) { UIImageSymbolConfiguration *config; if(icon.isSymbolImage) config = [UIImageSymbolConfiguration configurationWithPointSize:size weight:weight]; @@ -242,6 +242,16 @@ static BOOL overridePersistedFoldState = YES; } _iconImageView.tintColor = [ThemeManager textColor]; _iconImageView.hidden = (icon == nil); + + // 图标约束 + [NSLayoutConstraint activateConstraints:@[ + [_iconImageView.centerXAnchor constraintEqualToAnchor:_headerView.leadingAnchor constant:_leadingTrailingPadding+_headerViewHeight/2-3], + [_iconImageView.centerYAnchor constraintEqualToAnchor:_headerView.centerYAnchor], + // [_iconImageView.topAnchor constraintEqualToAnchor:_headerView.topAnchor], + [_iconImageView.widthAnchor constraintEqualToConstant:_headerViewHeight+constant], + [_iconImageView.heightAnchor constraintEqualToConstant:_headerViewHeight+constant] + ]]; + [self updateLayout]; } @@ -381,7 +391,7 @@ static BOOL overridePersistedFoldState = YES; self.heightConstraint.constant = headerHeight + _headerViewVerticalSpacing + rootStackViewHeight + _separatorLinePadding + 1; [UIView animateWithDuration:0 animations:^{ - self.toggleButton.transform = CGAffineTransformMakeRotation(M_PI+M_PI_2); + self.toggleButton.transform = CGAffineTransformMakeRotation(M_PI/2); [NSLayoutConstraint activateConstraints:@[ [self.rootStackView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:-self.separatorLinePadding], // [self.rootStackView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:0], diff --git a/VoidLink/ThemeManager.h b/VoidLink/ThemeManager.h deleted file mode 100644 index 781727d2..00000000 --- a/VoidLink/ThemeManager.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// ThemeManager.h -// VoidLink -// -// Created by True砖家 on 2025.5.25. -// Copyright © 2025 True砖家 @ Bilibili. All rights reserved. -// - -#import - -extern NSString * const ThemeDidChangeNotification; - -@interface ThemeManager:NSObject - -@property (class, nonatomic, assign) UIUserInterfaceStyle userInterfaceStyle; -+ (UIColor *)appPrimaryColor; -+ (UIColor *)appSecondaryColor; -+ (UIColor *)appPrimaryColorWithAlpha; -+ (UIColor *)widgetBackgroundColor; -+ (UIColor *)appBackgroundColor; -+ (UIColor *)separatorColor; -+ (UIColor *)textColor; -+ (UIColor *)textColorGray; -+ (UIColor *)lowProfileGray; -+ (UIColor *)textTintColorWithAlpha; - -@end diff --git a/VoidLink/ThemeManager.m b/VoidLink/ThemeManager.m deleted file mode 100644 index 9b1b3523..00000000 --- a/VoidLink/ThemeManager.m +++ /dev/null @@ -1,152 +0,0 @@ -// -// ThemeManager.h -// VoidLink -// -// Created by True砖家 on 2025.5.25. -// Copyright © 2025 True砖家 @ Bilibili. All rights reserved. -// - -#import "ThemeManager.h" - -NSString * const ThemeDidChangeNotification = @"ThemeDidChangeNotification"; - -@implementation ThemeManager - -static UIUserInterfaceStyle _privateUserInterfaceStyle = UIUserInterfaceStyleUnspecified; -static UIUserInterfaceStyle _userInterfaceStyle; - -+ (UIColor *)setPublicUIStyle{ - if (@available(iOS 13.0, *)) { - UITraitCollection *traitCollection = [UIScreen mainScreen].traitCollection; - if(_privateUserInterfaceStyle == UIUserInterfaceStyleUnspecified) { - _userInterfaceStyle = traitCollection.userInterfaceStyle; - } - else _userInterfaceStyle = _privateUserInterfaceStyle; - return [UIColor clearColor]; - } else { - return [UIColor clearColor]; - } -} - -+ (UIUserInterfaceStyle)userInterfaceStyle { - [ThemeManager setPublicUIStyle]; - return _userInterfaceStyle; -} - -+ (void)setUserInterfaceStyle:(UIUserInterfaceStyle)style { - _privateUserInterfaceStyle = style; - if (_userInterfaceStyle == style) { - return; - } - [ThemeManager setPublicUIStyle]; - [[NSNotificationCenter defaultCenter] postNotificationName:ThemeDidChangeNotification object:nil]; -} - -+ (UIColor *)appBackgroundColor { - [ThemeManager setPublicUIStyle]; - switch (self.userInterfaceStyle) { - case UIUserInterfaceStyleLight: - return [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0]; - break; - case UIUserInterfaceStyleDark: - default: - return [UIColor colorWithRed:28.0/255.0 green:28.0/255.0 blue:30.0/255.0 alpha:1.0]; - //return [UIColor blackColor]; - break; - } -} - -+ (UIColor *)widgetBackgroundColor { - [ThemeManager setPublicUIStyle]; - switch (self.userInterfaceStyle) { - case UIUserInterfaceStyleLight: - return [UIColor whiteColor]; - break; - case UIUserInterfaceStyleDark: - default: - return [UIColor colorWithRed:44.0/255.0 green:44.0/255.0 blue:46.0/255.0 alpha:1.0]; - break; - } -} - -+ (UIColor *)separatorColor { - [ThemeManager setPublicUIStyle]; - switch (self.userInterfaceStyle) { - case UIUserInterfaceStyleLight: - return [UIColor colorWithWhite:0.1 alpha:0.28]; - break; - case UIUserInterfaceStyleDark: - default: - return [UIColor colorWithWhite:0.28 alpha:1.0]; - break; - } - } - - -+ (UIColor *)textColor { - [ThemeManager setPublicUIStyle]; - switch (self.userInterfaceStyle) { - case UIUserInterfaceStyleLight: - return [UIColor blackColor]; - break; - case UIUserInterfaceStyleDark: - default: - return [UIColor whiteColor]; - break; - } -} - -+ (UIColor *)appPrimaryColor { - return [UIColor colorWithRed:0.0 green:0.48 blue:1.0 alpha:1.0]; // #0A84FF -} - -+ (UIColor *)appSecondaryColor { - // return [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0]; // 可换其他常用色 - UIColor* originalColor = [ThemeManager appPrimaryColor]; - - UIColor *grayColor = [UIColor grayColor]; - CGFloat mixRatio = 0.3; // 混合比例,0.0 到 1.0 - - CGFloat r1, g1, b1, a1; - CGFloat r2, g2, b2, a2; - - [originalColor getRed:&r1 green:&g1 blue:&b1 alpha:&a1]; - [grayColor getRed:&r2 green:&g2 blue:&b2 alpha:&a2]; - - CGFloat r = r1 * (1 - mixRatio) + r2 * mixRatio; - CGFloat g = g1 * (1 - mixRatio) + g2 * mixRatio; - CGFloat b = b1 * (1 - mixRatio) + b2 * mixRatio; - CGFloat a = a1 * (1 - mixRatio) + a2 * mixRatio; - - UIColor *tonedColor = [UIColor colorWithRed:r green:g blue:b alpha:a]; - - return tonedColor; // 可换其他常用色 -} - -+ (UIColor *)appPrimaryColorWithAlpha { - [ThemeManager setPublicUIStyle]; - switch (self.userInterfaceStyle) { - case UIUserInterfaceStyleLight: - return [[ThemeManager appPrimaryColor] colorWithAlphaComponent:0.24]; // #0A84FF - break; - case UIUserInterfaceStyleDark: - default: - return [[ThemeManager appPrimaryColor] colorWithAlphaComponent:0.24]; - break; - } -} - -+ (UIColor *)textTintColorWithAlpha{ - return [[ThemeManager appPrimaryColor] colorWithAlphaComponent:0.24]; -} - -+ (UIColor *)textColorGray{ - return [UIColor colorWithRed:0.55 green:0.55 blue:0.6 alpha:0.95]; -} - -+ (UIColor *)lowProfileGray{ - return [UIColor colorWithRed:0.65 green:0.65 blue:0.65 alpha:0.4]; -} - - -@end diff --git a/VoidLink/ThemeManager.swift b/VoidLink/ThemeManager.swift new file mode 100644 index 00000000..3fab29a5 --- /dev/null +++ b/VoidLink/ThemeManager.swift @@ -0,0 +1,273 @@ +// +// ThemeManager.swift +// VoidLink +// +// Created by True砖家 on 2026/3/6. +// Copyright © 2026 True砖家 @ Bilibili. All rights reserved. +// + + +import UIKit + +@objcMembers +class ThemeManager: NSObject { + + static let ThemeDidChangeNotification = "ThemeDidChangeNotification" + + private static var _privateUserInterfaceStyle: UIUserInterfaceStyle = .unspecified + private static var _userInterfaceStyle: UIUserInterfaceStyle = .unspecified + + @objc class func setPublicUIStyle() -> UIColor { + if #available(iOS 13.0, *) { + let traitCollection = UIScreen.main.traitCollection + if _privateUserInterfaceStyle == .unspecified { + _userInterfaceStyle = traitCollection.userInterfaceStyle + } else { + _userInterfaceStyle = _privateUserInterfaceStyle + } + } + return UIColor.clear + } + + @objc class func userInterfaceStyle() -> UIUserInterfaceStyle { + _ = setPublicUIStyle() + return _userInterfaceStyle + } + + @objc class func setUserInterfaceStyle(_ style: UIUserInterfaceStyle) { + _privateUserInterfaceStyle = style + + if _userInterfaceStyle == style { + return + } + + _ = setPublicUIStyle() + + NotificationCenter.default.post( + name: Notification.Name(ThemeDidChangeNotification), + object: nil + ) + } + + @objc class func menuBackgroundColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor( + red: 242.0/255.0, + green: 242.0/255.0, + blue: 247.0/255.0, + alpha: 1 + ) + + default: + if #available(iOS 13.0, *) { + let darkTraits = UITraitCollection(userInterfaceStyle: .dark) + return UIColor.secondarySystemBackground.resolvedColor(with: darkTraits) + } else { + return UIColor( + red: 28.0/255.0, + green: 28.0/255.0, + blue: 30.0/255.0, + alpha: 1 + ) + } + } + } + + @objc class func hostViewBackgroundColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor( + red: 242.0/255.0, + green: 242.0/255.0, + blue: 247.0/255.0, + alpha: 1 + ) + + default: + if #available(iOS 13.0, *) { + let darkTraits = UITraitCollection(userInterfaceStyle: .dark) + return UIColor.systemGroupedBackground.resolvedColor(with: darkTraits) + } else { + return UIColor.black + } + } + } + + @objc class func offlineHostIconBackgroundColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor( + red: 242.0/255.0, + green: 242.0/255.0, + blue: 247.0/255.0, + alpha: 1 + ) + + default: + return UIColor( + red: 17.0/255.0, + green: 17.0/255.0, + blue: 19.0/255.0, + alpha: 1 + ) + } + } + + @objc class func widgetBackgroundColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor.white + default: + if #available(iOS 13.0, *) { + // return UIColor.secondarySystemBackground + let darkTraits = UITraitCollection(userInterfaceStyle: .dark) + return UIColor.secondarySystemGroupedBackground.resolvedColor(with: darkTraits) + } else { + return UIColor( + red: 44.0/255.0, + green: 44.0/255.0, + blue: 46.0/255.0, + alpha: 1 + ) + } + } + } + + @objc class func separatorColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + if #available(iOS 13.0, *) { + let lightTraits = UITraitCollection(userInterfaceStyle: .light) + return UIColor.separator.resolvedColor(with: lightTraits) + } else { + return UIColor( + red: 214.0/255.0, + green: 214.0/255.0, + blue: 218.0/255.0, + alpha: 1 + ) + } + default: + if #available(iOS 13.0, *) { + let darkTraits = UITraitCollection(userInterfaceStyle: .dark) + return UIColor.separator.resolvedColor(with: darkTraits) + } else {return UIColor(white: 0.28, alpha: 1)} + } + } + + @objc class func hostCardSeparatorColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor(white: 0.1, alpha: 0.28) + default: + return UIColor(white: 0.28, alpha: 1) + } + } + + @objc class func textColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + return UIColor.black + default: + return UIColor.white + } + } + + @objc class func sectionLabelTextColor() -> UIColor { + _ = setPublicUIStyle() + + switch userInterfaceStyle() { + case .light: + if #available(iOS 13.0, *) { + let traits = UITraitCollection(userInterfaceStyle: .light) + return UIColor.label.resolvedColor(with: traits) + } else { + return UIColor.black + } + default: + if #available(iOS 13.0, *) { + let traits = UITraitCollection(userInterfaceStyle: .dark) + return UIColor.label.resolvedColor(with: traits) + } else { + return UIColor.black + } + } + } + + @objc class func appPrimaryColor() -> UIColor { + return UIColor( + red: 0.0, + green: 0.48, + blue: 1.0, + alpha: 1.0 + ) // #0A84FF + } + + @objc class func appSecondaryColor() -> UIColor { + + let originalColor = appPrimaryColor() + let grayColor = UIColor.gray + let mixRatio: CGFloat = 0.3 + + var r1: CGFloat = 0 + var g1: CGFloat = 0 + var b1: CGFloat = 0 + var a1: CGFloat = 0 + + var r2: CGFloat = 0 + var g2: CGFloat = 0 + var b2: CGFloat = 0 + var a2: CGFloat = 0 + + originalColor.getRed(&r1, green: &g1, blue: &b1, alpha: &a1) + grayColor.getRed(&r2, green: &g2, blue: &b2, alpha: &a2) + + let r = r1 * (1 - mixRatio) + r2 * mixRatio + let g = g1 * (1 - mixRatio) + g2 * mixRatio + let b = b1 * (1 - mixRatio) + b2 * mixRatio + let a = a1 * (1 - mixRatio) + a2 * mixRatio + + return UIColor(red: r, green: g, blue: b, alpha: a) + } + + @objc class func appPrimaryColorWithAlpha() -> UIColor { + return appPrimaryColor().withAlphaComponent(0.24) + } + + @objc class func textTintColorWithAlpha() -> UIColor { + return appPrimaryColor().withAlphaComponent(0.24) + } + + @objc class func textColorGray() -> UIColor { + return UIColor( + red: 0.55, + green: 0.55, + blue: 0.6, + alpha: 0.95 + ) + } + + @objc class func lowProfileGray() -> UIColor { + return UIColor( + red: 0.65, + green: 0.65, + blue: 0.65, + alpha: 0.4 + ) + } +} diff --git a/VoidLink/UIAppView.m b/VoidLink/UIAppView.m index b69b34f8..7dfea223 100644 --- a/VoidLink/UIAppView.m +++ b/VoidLink/UIAppView.m @@ -12,7 +12,7 @@ #import "UIAppView.h" #import "AppAssetManager.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" static const float REFRESH_CYCLE = 1.0f; diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index 5bf50ff4..5f9b8340 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -16,7 +16,7 @@ #import "OSCProfilesManager.h" #import "LocalizationHelper.h" #import "VoidLink-Swift.h" -#import "ThemeManager.h" +// #import "ThemeManager.h" #import "DataManager.h" @interface LayoutOnScreenControlsViewController () diff --git a/VoidLink/ViewControllers/HostCollectionViewController.m b/VoidLink/ViewControllers/HostCollectionViewController.m index df58ed3c..68f07fcc 100644 --- a/VoidLink/ViewControllers/HostCollectionViewController.m +++ b/VoidLink/ViewControllers/HostCollectionViewController.m @@ -9,7 +9,7 @@ #import "HostCollectionViewController.h" #import "HostCardView.h" #import "TemporaryHost.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" static const CGFloat cellOffsetY = 20; @@ -104,7 +104,7 @@ static const CGFloat cellOffsetY = 20; } - (void)updateTheme { - self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; + self.collectionView.backgroundColor = [ThemeManager hostViewBackgroundColor]; for (HostCell *cell in [self.collectionView visibleCells]) { [cell.cardView updateTheme]; } diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index 84bc1887..e719c3af 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -31,7 +31,6 @@ #import "Plot.h" #import "CustomEdgeSlideGestureRecognizer.h" #import "DataManager.h" -#import "ThemeManager.h" #import "FixedTintImageView.h" #import "VoidLink-Swift.h" @@ -376,7 +375,7 @@ static NSMutableSet* hostList; // [self.view bringSubviewToFront:self.collectionView]; self.hostCollectionVC.view.hidden = YES; self.collectionView.hidden = NO; - self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; + self.collectionView.backgroundColor = [ThemeManager hostViewBackgroundColor]; //self.view.backgroundColor = [ThemeManager appBackgroundColor]; [self.collectionView setContentOffset:CGPointZero animated:NO]; @@ -1481,7 +1480,7 @@ static NSMutableSet* hostList; else{ self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; // old ios depend on this, do not remove self.navigationController.navigationBar.barTintColor = [UIColor clearColor]; // ios 14 depend on this, do not remove - self.navigationController.navigationBar.barTintColor = [ThemeManager appBackgroundColor]; // ios 14 depend on this, do not remove + self.navigationController.navigationBar.barTintColor = [ThemeManager hostViewBackgroundColor]; // ios 14 depend on this, do not remove } } @@ -1490,7 +1489,7 @@ static NSMutableSet* hostList; Class appearanceClass = NSClassFromString(@"UINavigationBarAppearance"); navBarAppearanceStandard = [[appearanceClass alloc] init]; [navBarAppearanceStandard performSelector:@selector(configureWithOpaqueBackground)]; // 不透明 - [navBarAppearanceStandard setValue:[ThemeManager appBackgroundColor] forKey:@"backgroundColor"]; // 设置你需要的背景色 + [navBarAppearanceStandard setValue:[ThemeManager hostViewBackgroundColor] forKey:@"backgroundColor"]; // 设置你需要的背景色 [navBarAppearanceStandard setValue:nil forKey:@"shadowColor"]; // 设置你需要的背景色 NSDictionary* titleTextAttributes = @{ NSForegroundColorAttributeName: [ThemeManager textColor] @@ -1547,12 +1546,12 @@ static NSMutableSet* hostList; } - (void)updateTheme { - self.view.backgroundColor = [ThemeManager appBackgroundColor]; - self.hostCollectionVC.view.backgroundColor = [ThemeManager appBackgroundColor]; - self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; + self.view.backgroundColor = [ThemeManager hostViewBackgroundColor]; + self.hostCollectionVC.view.backgroundColor = [ThemeManager hostViewBackgroundColor]; + self.collectionView.backgroundColor = [ThemeManager hostViewBackgroundColor]; if (@available(iOS 13.0, *)) { - [navBarAppearanceStandard setValue:[ThemeManager appBackgroundColor] forKey:@"backgroundColor"]; + [navBarAppearanceStandard setValue:[ThemeManager hostViewBackgroundColor] forKey:@"backgroundColor"]; NSDictionary* titleTextAttributes = @{ NSForegroundColorAttributeName: [ThemeManager textColor] }; @@ -1999,7 +1998,7 @@ static NSMutableSet* hostList; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTheme) - name:ThemeDidChangeNotification + name:ThemeManager.ThemeDidChangeNotification object:nil]; /* this makes background color works*/ diff --git a/VoidLink/ViewControllers/SWRevealViewController.m b/VoidLink/ViewControllers/SWRevealViewController.m index 45f3935a..1a0902ff 100755 --- a/VoidLink/ViewControllers/SWRevealViewController.m +++ b/VoidLink/ViewControllers/SWRevealViewController.m @@ -31,7 +31,7 @@ #import "SWRevealViewController.h" #import "LocalizationHelper.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" #pragma mark - StatusBar Helper Function @@ -147,7 +147,7 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1 _rearNavView.translatesAutoresizingMaskIntoConstraints = NO; _safeAreaPadding.translatesAutoresizingMaskIntoConstraints = NO; // _rearNavView.backgroundColor = [UIColor lightGrayColor]; // 设置背景色以便查看 - _safeAreaPadding.backgroundColor = [ThemeManager appBackgroundColor]; + _safeAreaPadding.backgroundColor = [ThemeManager menuBackgroundColor]; // NSLog(@"_c.rearViewRevealWidth: %f", _c.rearViewRevealWidth); // _rearNavView.frame = CGRectMake(0, 0, _c.rearViewRevealWidth, 100); @@ -837,21 +837,21 @@ const int FrontViewPositionNone = 0xff; } - (void)updateTheme { - _contentView.backgroundColor = [ThemeManager appBackgroundColor]; - _contentView.rearNavView.backgroundColor = [ThemeManager appBackgroundColor]; - _contentView.safeAreaPadding.backgroundColor = [ThemeManager appBackgroundColor]; + _contentView.backgroundColor = [ThemeManager menuBackgroundColor]; + _contentView.rearNavView.backgroundColor = [ThemeManager menuBackgroundColor]; + _contentView.safeAreaPadding.backgroundColor = [ThemeManager menuBackgroundColor]; _separatorLine.backgroundColor = [ThemeManager separatorColor]; if (@available(iOS 13.0, *)) { UINavigationBarAppearance *navBarAppearanceStandard = _dockedNavBar.standardAppearance; - navBarAppearanceStandard.backgroundColor = [ThemeManager appBackgroundColor]; + navBarAppearanceStandard.backgroundColor = [ThemeManager menuBackgroundColor]; navBarAppearanceStandard.titleTextAttributes = @{ NSForegroundColorAttributeName: [ThemeManager textColor] }; _dockedNavBar.standardAppearance = navBarAppearanceStandard; _dockedNavBar.scrollEdgeAppearance = navBarAppearanceStandard; } else { - _dockedNavBar.barTintColor = [ThemeManager appBackgroundColor]; + _dockedNavBar.barTintColor = [ThemeManager menuBackgroundColor]; } } @@ -860,7 +860,7 @@ const int FrontViewPositionNone = 0xff; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTheme) - name:ThemeDidChangeNotification + name:ThemeManager.ThemeDidChangeNotification object:nil]; [self updateTheme]; } @@ -938,7 +938,7 @@ const int FrontViewPositionNone = 0xff; [_separatorLine.bottomAnchor constraintEqualToAnchor:_contentView.bottomAnchor constant:0], //[_separatorLine.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:self.bounds.size.width-60], [_separatorLine.leadingAnchor constraintEqualToAnchor:_contentView.frontView.leadingAnchor constant:0], - [_separatorLine.trailingAnchor constraintEqualToAnchor:_contentView.frontView.leadingAnchor constant:2], //mark: settingMenuLayout + [_separatorLine.trailingAnchor constraintEqualToAnchor:_contentView.frontView.leadingAnchor constant:0.7], //mark: settingMenuLayout ]]; } @@ -954,7 +954,7 @@ const int FrontViewPositionNone = 0xff; if (@available(iOS 13.0, *)) { UINavigationBarAppearance *navBarAppearanceStandard = [[UINavigationBarAppearance alloc] init]; [navBarAppearanceStandard configureWithOpaqueBackground]; // 不透明 - navBarAppearanceStandard.backgroundColor =[ThemeManager appBackgroundColor];; // 设置你需要的背景色 + navBarAppearanceStandard.backgroundColor =[ThemeManager menuBackgroundColor];; // 设置你需要的背景色 navBarAppearanceStandard.shadowColor = nil; // 去掉底部分割线(可选) navBarAppearanceStandard.titleTextAttributes = @{ NSForegroundColorAttributeName: [ThemeManager textColor] @@ -965,7 +965,7 @@ const int FrontViewPositionNone = 0xff; _dockedNavBar.scrollEdgeAppearance = navBarAppearanceStandard; } else { _dockedNavBar.barTintColor = [UIColor clearColor]; - _dockedNavBar.barTintColor = [ThemeManager appBackgroundColor]; + _dockedNavBar.barTintColor = [ThemeManager menuBackgroundColor]; _dockedNavBar.shadowImage = [UIImage new]; // remove bottom line for navbar } diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 0fe3bc18..e10ea5ab 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -12,7 +12,7 @@ #import "SettingsViewController.h" #import "TemporarySettings.h" #import "DataManager.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" #import "Connection.h" #import "Plot.h" #import "OSCProfilesManager.h" @@ -474,7 +474,7 @@ BOOL isCustomResolution(int resolutionSelected) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTheme) - name:ThemeDidChangeNotification + name:ThemeManager.ThemeDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -790,7 +790,7 @@ BOOL isCustomResolution(int resolutionSelected) { videoSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Video"]; videoSection.identifier = @"SettingsSectionVideo"; if (@available(iOS 13.0, *)) { - [videoSection setSectionWithIcon:[UIImage systemImageNamed:@"waveform"] andSize:20]; + [videoSection setSectionWithIcon:[UIImage systemImageNamed:@"waveform"] size:13 sizeConstraint:-17]; } [self addSetting:self.resolutionStack ofId:@"resolutionStack" withInfoTag:NO withDynamicLabel:YES to:videoSection]; [self addSetting:self.fpsStack ofId:@"fpsStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; @@ -812,7 +812,7 @@ BOOL isCustomResolution(int resolutionSelected) { touchControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch Control"]; touchControlSection.identifier = @"SettingsSectionTouch&Controller"; if (@available(iOS 13.0, *)) { - [touchControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5]; + [touchControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] size:22 sizeConstraint:-15]; } [self addSetting:self.touchModeStack ofId:@"touchModeStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection]; [self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection]; @@ -836,7 +836,7 @@ BOOL isCustomResolution(int resolutionSelected) { controllerSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Controller"]; controllerSection.identifier = @"SettingsSectionController"; if (@available(iOS 13.0, *)) { - [controllerSection setSectionWithIcon:[UIImage systemImageNamed:@"gamecontroller"] andSize:30]; + [controllerSection setSectionWithIcon:[UIImage systemImageNamed:@"gamecontroller"] size:30 sizeConstraint:-12]; } [self addSetting:self.swapAbxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:controllerSection]; [self addSetting:self.hapticEngineStack ofId:@"hapticEngineStack" withInfoTag:NO withDynamicLabel:NO to:controllerSection]; @@ -854,10 +854,7 @@ BOOL isCustomResolution(int resolutionSelected) { motionControlSection.delegate = self; motionControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Motion Control"]; motionControlSection.identifier = @"SettingsSectionMotionControl"; - if (@available(iOS 13.0, *)) { - // [motionControlSection setSectionWithIcon:[UIImage imageNamed:@"gyroscope"] andSize:23]; - [motionControlSection setSectionWithIcon:[UIImage imageNamed:@"gyroscope"] andSize:23]; - } + if (@available(iOS 13.0, *)) [motionControlSection setSectionWithIcon:[UIImage imageNamed:@"gyroscope"] size:23 sizeConstraint:-20]; [self addSetting:self.controllerGyroSwitchButtonStack ofId:@"controllerGyroSwitchButtonStack" withInfoTag:YES withDynamicLabel:YES to:motionControlSection]; [self addSetting:self.reverseHoldButtonStack ofId:@"reverseHoldButtonStack" withInfoTag:YES withDynamicLabel:YES to:motionControlSection]; [self addSetting:self.mapGyroToStack ofId:@"mapGyroToStack" withInfoTag:YES withDynamicLabel:NO to:motionControlSection]; @@ -882,7 +879,7 @@ BOOL isCustomResolution(int resolutionSelected) { pencilSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Drawing Toolkit"]; pencilSection.identifier = @"SettingsSectionPencil"; if (@available(iOS 13.0, *)) { - [pencilSection setSectionWithIcon:[UIImage systemImageNamed:@"pencil.and.outline"] size:19 weight:UIImageSymbolWeightHeavy]; + [pencilSection setSectionWithIcon:[UIImage systemImageNamed:@"pencil.and.outline"] size:19 weight:UIImageSymbolWeightHeavy sizeConstraint:-17.5]; } [self addSetting:self.pencilTickStack ofId:@"pencilTickStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection]; [self addSetting:self.pencilTickIntervalStack ofId:@"pencilTickIntervalStack" withInfoTag:NO withDynamicLabel:YES to:pencilSection]; @@ -901,7 +898,7 @@ BOOL isCustomResolution(int resolutionSelected) { gesturesSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Gestures"]; gesturesSection.identifier = @"SettingsSectionGestures"; if (@available(iOS 13.0, *)) { - [gesturesSection setSectionWithIcon:[UIImage systemImageNamed:@"hand.draw"] andSize:23]; + [gesturesSection setSectionWithIcon:[UIImage systemImageNamed:@"hand.draw"] size:23 sizeConstraint:-13.3]; } [self addSetting:self.softKeyboardGestureStack ofId:@"softKeyboardGestureStack" withInfoTag:YES withDynamicLabel:NO to:gesturesSection]; @@ -917,7 +914,7 @@ BOOL isCustomResolution(int resolutionSelected) { peripheralSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Peripherals"]; peripheralSection.identifier = @"SettingsSectionPeripherals"; if (@available(iOS 13.0, *)) { - [peripheralSection setSectionWithIcon:[UIImage imageNamed:@"cable.connector.video"] andSize:20]; + [peripheralSection setSectionWithIcon:[UIImage imageNamed:@"cable.connector.video"] size:20 sizeConstraint:-17.9]; } if (@available(iOS 13.0, *)) { [self addSetting:self.externalDisplayModeStack ofId:@"externalDisplayModeStack" withInfoTag:YES withDynamicLabel:NO to:peripheralSection]; @@ -935,7 +932,7 @@ BOOL isCustomResolution(int resolutionSelected) { audioSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Audio"]; audioSection.identifier = @"SettingsSectionAudio"; if (@available(iOS 13.0, *)) { - [audioSection setSectionWithIcon:[UIImage imageNamed:@"speaker.wave.2"] andSize:20]; + [audioSection setSectionWithIcon:[UIImage imageNamed:@"speaker.wave.2"] size:20 sizeConstraint:-16.7]; } [self addSetting:self.audioOnPcStack ofId:@"audioOnPcStack" withInfoTag:NO withDynamicLabel:NO to:audioSection]; @@ -957,7 +954,7 @@ BOOL isCustomResolution(int resolutionSelected) { otherSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Others"]; otherSection.identifier = @"SettingsSectionOthers"; if (@available(iOS 13.0, *)) { - [otherSection setSectionWithIcon:[UIImage systemImageNamed:@"cube"] andSize:20.5]; + [otherSection setSectionWithIcon:[UIImage systemImageNamed:@"cube"] size:20.5 sizeConstraint:-17]; } [self addSetting:self.statsOverlayStack ofId:@"statsOverlayStack" withInfoTag:NO withDynamicLabel:NO to:otherSection]; [self addSetting:self.unlockDisplayOrientationStack ofId:@"unlockDisplayOrientationStack" withInfoTag:YES withDynamicLabel:NO to:otherSection]; @@ -977,7 +974,7 @@ BOOL isCustomResolution(int resolutionSelected) { experimentalSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Experimental"]; experimentalSection.identifier = @"SettingsSectionExperimental"; if (@available(iOS 13.0, *)) { - [experimentalSection setSectionWithIcon:[UIImage imageNamed:@"flask"] andSize:20]; + [experimentalSection setSectionWithIcon:[UIImage imageNamed:@"flask"] size:20 sizeConstraint:-19]; } [self addSetting:self.touchModeStack2 ofId:@"touchModeStack2" withInfoTag:NO withDynamicLabel:NO to:experimentalSection]; @@ -3388,8 +3385,9 @@ BOOL isCustomResolution(int resolutionSelected) { for (UIView *subview in view.subviews) { if ([subview isKindOfClass:[MenuSectionView class]]) { MenuSectionView *section = (MenuSectionView *)subview; + section.titleLabel.textColor = [ThemeManager sectionLabelTextColor]; section.iconImageView.tintColor = [UIColor clearColor]; - section.iconImageView.tintColor = [ThemeManager textColor]; + section.iconImageView.tintColor = [ThemeManager sectionLabelTextColor]; section.separatorLine.backgroundColor = [UIColor clearColor]; section.separatorLine.backgroundColor = [ThemeManager separatorColor]; } @@ -3399,7 +3397,7 @@ BOOL isCustomResolution(int resolutionSelected) { - (void)updateTheme{ self.view.backgroundColor = [UIColor clearColor]; - self.view.backgroundColor = [ThemeManager appBackgroundColor]; + self.view.backgroundColor = [ThemeManager menuBackgroundColor]; [self updateThemeForMenuSections:self.view]; [self updateThemeForLabels:self.view]; [self updateThemeForSelectors:self.view]; diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 30651e5f..6b866fb5 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -25,7 +25,7 @@ #import "LocalizationHelper.h" #import "VoidLink-Swift.h" #import "OSCProfilesManager.h" -#import "ThemeManager.h" +#import "VoidLink-Swift.h" #import "NativeTouchPointer.h" #include @@ -585,7 +585,7 @@ } - (void)updateTheme { - self.view.backgroundColor = [ThemeManager appBackgroundColor]; + self.view.backgroundColor = [ThemeManager menuBackgroundColor]; _stageLabel.textColor = [[ThemeManager textColor] colorWithAlphaComponent:0.9]; _spinner.color = [ThemeManager textColor]; } diff --git a/VoidLink/VoidLink-Bridging-Header.h b/VoidLink/VoidLink-Bridging-Header.h index 86a73d26..278a38e7 100644 --- a/VoidLink/VoidLink-Bridging-Header.h +++ b/VoidLink/VoidLink-Bridging-Header.h @@ -9,5 +9,4 @@ #import "OSCProfilesManager.h" #import "opus.h" #import "opus_defines.h" -#import "ThemeManager.h" // #import "RelativeTouchHandler.h"