diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard
index 42081400..c9240cef 100644
--- a/Limelight/Base.lproj/iPad.storyboard
+++ b/Limelight/Base.lproj/iPad.storyboard
@@ -64,17 +64,17 @@
-
+
-
-
-
+
-
+
-
+
-
+
@@ -119,39 +116,39 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -163,21 +160,21 @@
-
+
-
+
-
+
-
+
@@ -187,14 +184,14 @@
-
+
-
+
-
+
@@ -202,20 +199,20 @@
-
+
-
+
-
+
-
+
@@ -223,20 +220,20 @@
-
+
-
+
-
+
-
+
@@ -244,20 +241,20 @@
-
+
-
+
-
+
-
+
@@ -265,27 +262,27 @@
-
+
-
+
-
+
-
+
-
+
@@ -297,14 +294,14 @@
-
+
-
+
-
+
@@ -316,27 +313,27 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
-
+
@@ -346,21 +343,21 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -370,21 +367,21 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -394,21 +391,21 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -419,41 +416,41 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
@@ -463,20 +460,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -486,20 +483,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -509,20 +506,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -532,20 +529,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -557,20 +554,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -580,20 +577,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -603,20 +600,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -626,20 +623,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -649,20 +646,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -672,20 +669,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -696,20 +693,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -719,20 +716,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -742,20 +739,20 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
+
-
+
@@ -766,11 +763,11 @@ ICAgICAgICAgICAgICA
-
+
-
+
@@ -858,7 +855,7 @@ ICAgICAgICAgICAgICA
-
+
@@ -889,8 +886,7 @@ ICAgICAgICAgICAgICA
-
-
+
@@ -898,7 +894,7 @@ ICAgICAgICAgICAgICA
-
+
@@ -1271,16 +1267,13 @@ ICAgICAgICAgICAgICA
-
+
-
-
-
-
+
diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard
index 90c47271..660ba759 100644
--- a/Limelight/Base.lproj/iPhone.storyboard
+++ b/Limelight/Base.lproj/iPhone.storyboard
@@ -1,9 +1,9 @@
-
+
-
+
@@ -13,7 +13,7 @@
-
+
@@ -43,7 +43,8 @@
-
+
+
@@ -648,7 +649,7 @@ ICAgICAgICAgICAgIA
-
+
@@ -955,12 +956,12 @@ ICAgICAgICAgICAgIA
-
+
-
+
diff --git a/Limelight/HostCardView.m b/Limelight/HostCardView.m
index 6a31fe28..21c1039b 100644
--- a/Limelight/HostCardView.m
+++ b/Limelight/HostCardView.m
@@ -61,7 +61,6 @@ static const float REFRESH_CYCLE = 2.0f;
defaultGreen = [UIColor colorWithRed:52.0/255.0 green:199.0/255.0 blue:89.0/255.0 alpha:1.0];
// self.userIterfaceStyle = UIUserInterfaceStyleLight
if (@available(iOS 13.0, *)) {
- NSLog(@"ttesttttt");
UIContextMenuInteraction* longPressInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
[self addInteraction:longPressInteraction];
self.userInteractionEnabled = YES;
@@ -154,7 +153,6 @@ static const float REFRESH_CYCLE = 2.0f;
- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
configurationForMenuAtLocation:(CGPoint)location API_AVAILABLE(ios(13.0)){
- NSLog(@"long tap test");
longPressFired = true;
if ([self.delegate respondsToSelector:@selector(hostCardLongPressed:view:)]) {
[self.delegate hostCardLongPressed:_host view:self];
diff --git a/Limelight/Images.xcassets/disconnect.imageset/Contents.json b/Limelight/Images.xcassets/disconnect.imageset/Contents.json
new file mode 100644
index 00000000..9f10bd77
--- /dev/null
+++ b/Limelight/Images.xcassets/disconnect.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "disconnect.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Limelight/Images.xcassets/disconnect.imageset/disconnect.svg b/Limelight/Images.xcassets/disconnect.imageset/disconnect.svg
new file mode 100644
index 00000000..75d1b5f3
--- /dev/null
+++ b/Limelight/Images.xcassets/disconnect.imageset/disconnect.svg
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Limelight/MenuSectionView.m b/Limelight/MenuSectionView.m
index 6df6311e..3b12b415 100644
--- a/Limelight/MenuSectionView.m
+++ b/Limelight/MenuSectionView.m
@@ -8,6 +8,7 @@
// MenuSectionView.m
#import "MenuSectionView.h"
+#import "ThemeManager.h"
@interface MenuSectionView ()
@@ -67,13 +68,14 @@
_iconImageView = [[UIImageView alloc] init];
_iconImageView.contentMode = UIViewContentModeScaleAspectFit;
_iconImageView.translatesAutoresizingMaskIntoConstraints = NO;
- _iconImageView.tintColor = [UIColor whiteColor];
+ _iconImageView.tintColor = [ThemeManager textColor];
[_headerView addSubview:_iconImageView];
// 标题标签
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = _sectionTitle;
_titleLabel.font = [UIFont systemFontOfSize:27 weight:UIFontWeightMedium];
+ _titleLabel.textColor = [ThemeManager textColor];
_titleLabel.textAlignment = NSTextAlignmentLeft;
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_headerView addSubview:_titleLabel];
@@ -105,7 +107,7 @@
// 分隔线
_separatorLine = [[UIView alloc] init];
- _separatorLine.backgroundColor = [UIColor colorWithWhite:0.2 alpha:5.0];
+ _separatorLine.backgroundColor = [ThemeManager separatorColor];
_separatorLine.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_separatorLine];
@@ -187,7 +189,14 @@
#pragma mark - Public Methods
- (void)setSectionIcon:(UIImage *)icon {
- _iconImageView.image = icon;
+ if (@available(iOS 13.0, *)) {
+ UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithWeight:UIImageSymbolWeightSemibold];
+ _iconImageView.image = [icon imageWithConfiguration:config];
+
+ } else {
+ _iconImageView.image = icon;
+ }
+
_iconImageView.hidden = (icon == nil);
[self updateLayout];
}
@@ -287,7 +296,7 @@
[self setupConstraints];
if (_expanded) {
_rootStackView.hidden = NO;
- _separatorLine.hidden = NO;
+ _separatorLine.hidden = YES;
CGSize fittingSize = [self.rootStackView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
CGFloat rootStackViewHeight = fittingSize.height;
fittingSize = [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
diff --git a/Limelight/ThemeManager.m b/Limelight/ThemeManager.m
index 21cb4e6c..2e145f5b 100644
--- a/Limelight/ThemeManager.m
+++ b/Limelight/ThemeManager.m
@@ -47,6 +47,7 @@ static UIUserInterfaceStyle _userInterfaceStyle;
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;
}
}
@@ -68,12 +69,10 @@ static UIUserInterfaceStyle _userInterfaceStyle;
[ThemeManager getUIStyle];
switch (self.userInterfaceStyle) {
case UIUserInterfaceStyleLight:
- NSLog(@"themeLightSP");
return [UIColor colorWithWhite:0.1 alpha:0.28];
break;
case UIUserInterfaceStyleDark:
default:
- NSLog(@"themeDarkSP");
return [UIColor colorWithWhite:0.28 alpha:1.0];
break;
}
@@ -84,12 +83,10 @@ static UIUserInterfaceStyle _userInterfaceStyle;
[ThemeManager getUIStyle];
switch (self.userInterfaceStyle) {
case UIUserInterfaceStyleLight:
- NSLog(@"themeLightTX");
return [UIColor blackColor];
break;
case UIUserInterfaceStyleDark:
default:
- NSLog(@"themeDarkTX");
return [UIColor whiteColor];
break;
}
@@ -100,7 +97,7 @@ static UIUserInterfaceStyle _userInterfaceStyle;
}
+ (UIColor *)appSecondaryColor {
- return [UIColor colorWithRed:0.0 green:0.48 blue:1.0 alpha:1.0]; // 可换其他常用色
+ return [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0]; // 可换其他常用色
}
+ (UIColor *)appPrimaryColorWithAlpha {
diff --git a/Limelight/UIAppView.m b/Limelight/UIAppView.m
index 961d79c4..3b966571 100644
--- a/Limelight/UIAppView.m
+++ b/Limelight/UIAppView.m
@@ -142,7 +142,6 @@ static UIImage* noImage;
if (appImage != nil) {
// This size of image might be blank image received from GameStream.
- //AppImage TESTTTTTTTT
// TODO: Improve no-app image detection
if (!(appImage.size.width == 130.f && appImage.size.height == 180.f) && // GFE 2.0
!(appImage.size.width == 628.f && appImage.size.height == 888.f)){
diff --git a/Limelight/ViewControllers/HostCollectionViewController.m b/Limelight/ViewControllers/HostCollectionViewController.m
index c7b8fa47..61fad01e 100644
--- a/Limelight/ViewControllers/HostCollectionViewController.m
+++ b/Limelight/ViewControllers/HostCollectionViewController.m
@@ -73,11 +73,21 @@ static const CGFloat cellOffsetY = 20;
@implementation HostCollectionViewController{
UICollectionViewFlowLayout *layout;
+ CGFloat _horizontalPadding;
}
- (instancetype)init {
layout = [[UICollectionViewFlowLayout alloc] init];
- layout.sectionInset = UIEdgeInsetsMake(7, 0, 0, 0); // 上、左、下、右的间距
+ switch ([UIDevice currentDevice].userInterfaceIdiom) {
+ case UIUserInterfaceIdiomPhone:
+ _horizontalPadding = 5;
+ break;
+ case UIUserInterfaceIdiomPad:
+ default:
+ _horizontalPadding = 75;
+ break;
+ }
+ layout.sectionInset = UIEdgeInsetsMake(7, _horizontalPadding, 0, _horizontalPadding); // 上、左、下、右的间距
if (self = [super initWithCollectionViewLayout:layout]) {
_interItemMinimumSpacing = 10;
_minimumLineSpacing = 10;
@@ -177,9 +187,9 @@ static const CGFloat cellOffsetY = 20;
_collectionViewHeightConstraint.constant = contentHeight;
}
- if([self numberOfRowsInCollectionView]<=2 && !contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(50, 0, 0, 0);
- if([self numberOfRowsInCollectionView]>2 && !contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(25, 0, 0, 0);
- if(contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(7, 0, 0, 0);
+ if([self numberOfRowsInCollectionView]<=2 && !contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(50, _horizontalPadding, 0, _horizontalPadding);
+ if([self numberOfRowsInCollectionView]>2 && !contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(25, _horizontalPadding, 0, _horizontalPadding);
+ if(contentExceedsView) layout.sectionInset = UIEdgeInsetsMake(7, _horizontalPadding, 0, _horizontalPadding);
}
#pragma mark - UICollectionView DataSource
diff --git a/Limelight/ViewControllers/MainFrameViewController.h b/Limelight/ViewControllers/MainFrameViewController.h
index 56956aed..5ef880e5 100644
--- a/Limelight/ViewControllers/MainFrameViewController.h
+++ b/Limelight/ViewControllers/MainFrameViewController.h
@@ -25,7 +25,6 @@
@property (weak, nonatomic) IBOutlet UIBarButtonItem *settingsButton;
#if !TARGET_OS_TV
-@property (weak, nonatomic) IBOutlet UIBarButtonItem *upButton;
@property (nonatomic, assign) bool settingsExpandedInStreamView;
@property (nonatomic, strong) HostCollectionViewController *hostCollectionVC;
@property (weak, nonatomic) IBOutlet UINavigationItem *navigationItem;
diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m
index 1eb6eedb..4e7fd61e 100644
--- a/Limelight/ViewControllers/MainFrameViewController.m
+++ b/Limelight/ViewControllers/MainFrameViewController.m
@@ -48,8 +48,10 @@
@implementation MainFrameViewController {
UILabel* waterMark;
- UIBarButtonItem* addHostButton;
- UIBarButtonItem* helpButton;
+ UIBarButtonItem* _addHostButton;
+ UIBarButtonItem* _helpButton;
+ UIBarButtonItem* _upButton;
+
UILabel* hostViewTitleLabel;
//CGFloat recordedScreenWidth;
NSOperationQueue* _opQueue;
@@ -66,6 +68,9 @@
NSArray* _sortedAppList;
NSCache* _boxArtCache;
bool _background;
+ UINavigationBarAppearance *navBarAppearanceStandard;
+ UINavigationBarAppearance *navBarAppearanceScroll;
+
#if TARGET_OS_TV
UITapGestureRecognizer* _menuRecognizer;
#endif
@@ -131,10 +136,12 @@ static NSMutableSet* hostList;
- (void)updateTitle {
- self.navigationController.navigationBar.titleTextAttributes = @{
- NSFontAttributeName: [UIFont systemFontOfSize:20 weight:UIFontWeightMedium],
- NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
- };
+ if (@available(iOS 13.0, *)) {
+ navBarAppearanceScroll.titleTextAttributes = navBarAppearanceStandard.titleTextAttributes = @{
+ NSFontAttributeName: [UIFont systemFontOfSize:20 weight:UIFontWeightMedium],
+ NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
+ };
+ }
if (_selectedHost != nil) {
self.title = _selectedHost.name;
@@ -144,13 +151,25 @@ static NSMutableSet* hostList;
self.title = [LocalizationHelper localizedStringForKey: @"Searching for PCs on your network..."] ;
}
else {
+ if (@available(iOS 13.0, *)) {
+ navBarAppearanceScroll.titleTextAttributes = navBarAppearanceStandard.titleTextAttributes = @{
+ NSFontAttributeName: [UIFont systemFontOfSize:24 weight:UIFontWeightSemibold],
+ NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
+ };
+ }
+ /*
self.navigationController.navigationBar.titleTextAttributes = @{
NSFontAttributeName: [UIFont systemFontOfSize:24 weight:UIFontWeightSemibold],
NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
- };
+ };*/
self.title = [LocalizationHelper localizedStringForKey: @"Hosts" ];
//self.title = nil;
}
+ if (@available(iOS 13.0, *)) {
+ [self applyNavBarAppearance];
+ } else {
+ // Fallback on earlier versions
+ }
}
- (void)alreadyPaired {
@@ -311,10 +330,11 @@ static NSMutableSet* hostList;
_selectedHost = nil;
_sortedAppList = nil;
- [self.collectionView removeFromSuperview]; // necessary for new scroll host view reloading mechanism
+ // [self.collectionView removeFromSuperview]; // necessary for new scroll host view reloading mechanism
+ self.hostCollectionVC.view.hidden = NO;
+ self.collectionView.hidden = YES;
[self updateTitle];
- self.navigationItem.rightBarButtonItems = @[helpButton, addHostButton];
- [self->_upButton setTitle:nil];
+ self.navigationItem.rightBarButtonItems = @[_helpButton, _addHostButton];
self.revealViewController.mainFrameIsInHostView = true; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view
}
@@ -341,14 +361,19 @@ static NSMutableSet* hostList;
//_appManager = [[AppAssetManager alloc] initWithCallback:self];
[self.collectionView setCollectionViewLayout:self.collectionViewLayout];
[self.collectionView reloadData]; //for new scroll host view reloading mechanism
- [self.view addSubview:self.collectionView]; //for new scroll host view reloading mechanism
+ // [self.view bringSubviewToFront:self.collectionView];
+ self.hostCollectionVC.view.hidden = YES;
+ self.collectionView.hidden = NO;
+ self.collectionView.backgroundColor = [ThemeManager appBackgroundColor];
[self attachWaterMark];
- [self->_upButton setTitle: [LocalizationHelper localizedStringForKey: @"Select New Host"]];
self.navigationItem.rightBarButtonItems = @[_upButton];
self.revealViewController.mainFrameIsInHostView = false;
// [self disableNavigation];
[self updateTitle];
[self alreadyPaired];
+ // self.navigationController.navigationBar.backgroundColor = [ThemeManager appBackgroundColor];
+ // self.navigationController.navigationBar.translucent = NO;
+ //[self applyNavBarAppearance:navBarAppearance];
}
- (void)appButtonTappedForHost:(TemporaryHost *)host {
@@ -1038,12 +1063,6 @@ static NSMutableSet* hostList;
}
#if !TARGET_OS_TV
-// this method is deprecated
-- (void)simulateSettingsButtonPressClose { //force expand settings view to update resolution table, and all setting includes current fullscreen resolution will be updated.
- if (currentPosition == FrontViewPositionRight && _settingsButton.target && [_settingsButton.target respondsToSelector:_settingsButton.action]) {
- [_settingsButton.target performSelector:_settingsButton.action withObject:_settingsButton];
- }
-}
- (void)simulateSettingsButtonPress { //simulate pressing the setting button, called from setting view controller.
//if([self isIPhonePortrait]) return; // disable settings view expanding in iphone portrait mode since it's buggy.
@@ -1053,15 +1072,15 @@ static NSMutableSet* hostList;
}
- (void)handleOrientationChange {
- UIDeviceOrientation targetOrientation = [[UIDevice currentDevice] orientation];
- if([self isIPhone] && UIDeviceOrientationIsPortrait(targetOrientation)) [self simulateSettingsButtonPressClose]; // on iphone, force close settings views if target orietation is portrait.
+ // UIDeviceOrientation targetOrientation = [[UIDevice currentDevice] orientation];
+ // if([self isIPhone] && UIDeviceOrientationIsPortrait(targetOrientation)) [self simulateSettingsButtonPressClose]; // on iphone, force close settings views if target orietation is portrait.
double delayInSeconds = 0.7;
// Convert the delay into a dispatch_time_t value
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
// Perform some task after the delay
dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay
// [self updateResolutionAccordingly];
- [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode.
+ // [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode.
});
}
@@ -1075,23 +1094,21 @@ static NSMutableSet* hostList;
}
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position {
-
+ SettingsViewController* settingsViewController = (SettingsViewController*)[revealController rearViewController];
+
if (position == FrontViewPositionLeft) {
self.navigationItem.leftBarButtonItems = @[_settingsButton];
}
else {
self.navigationItem.leftBarButtonItems = @[];
+ [settingsViewController updateTheme];
}
- SettingsViewController* settingsViewController = (SettingsViewController*)[revealController rearViewController];
settingsViewController.mainFrameViewController = self;
// enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable.
- if (@available(iOS 16.0, *)) {
- revealController.disconnectButton.hidden = !self.settingsExpandedInStreamView;
- } else {
- revealController.disconnectButton.enabled = self.settingsExpandedInStreamView;
- // Fallback on earlier versions
- }
+ if(self.settingsExpandedInStreamView) [revealController buttonsInStreaming];
+ else [revealController buttonsNotInStreaming];
+
[settingsViewController.resolutionSelector setEnabled:!self.settingsExpandedInStreamView];
settingsViewController.resolutionStack.hidden = self.settingsExpandedInStreamView;
[settingsViewController.framerateSelector setEnabled:!self.settingsExpandedInStreamView];
@@ -1351,19 +1368,47 @@ static NSMutableSet* hostList;
]];
}
+- (void)applyNavBarAppearance API_AVAILABLE(ios(13.0)){
+ self.navigationController.navigationBar.standardAppearance = navBarAppearanceStandard;
+ self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearanceStandard;
+}
- (void)setupNavBar{
+ if (@available(iOS 13.0, *)) {
+ navBarAppearanceStandard = [[UINavigationBarAppearance alloc] init];
+ [navBarAppearanceStandard configureWithOpaqueBackground]; // 不透明
+ navBarAppearanceStandard.backgroundColor =[ThemeManager appBackgroundColor];; // 设置你需要的背景色
+ navBarAppearanceStandard.shadowColor = nil; // 去掉底部分割线(可选)
+ navBarAppearanceStandard.titleTextAttributes = @{
+ NSForegroundColorAttributeName: [ThemeManager textColor]
+ };
+ navBarAppearanceStandard.shadowColor = [UIColor clearColor];
+ navBarAppearanceStandard.backgroundImage = nil;
+
+ /*
+ navBarAppearanceScroll = [[UINavigationBarAppearance alloc] init];
+ [navBarAppearanceScroll configureWithTransparentBackground];
+ navBarAppearanceScroll.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
+ navBarAppearanceScroll.backgroundColor =[[ThemeManager appBackgroundColor] colorWithAlphaComponent:0.6]; // 设置你需要的背景色
+ //navBarAppearanceScroll.shadowColor = nil; // 去掉底部分割线(可选)
+ navBarAppearanceScroll.titleTextAttributes = @{
+ NSForegroundColorAttributeName: [ThemeManager textColor]
+ };
+ // navBarAppearanceScroll.shadowColor = [UIColor clearColor];
+ navBarAppearanceScroll.backgroundImage = nil;*/
+
+ //appearance.
+ [self applyNavBarAppearance];
+ }
- self->addHostButton = [self createAddHostButton];
- self->helpButton = [self createHelpButton];
+ self->_addHostButton = [self createAddHostButton];
+ self->_helpButton = [self createHelpButton];
//[self setupHostViewTitle];
- self.navigationItem.rightBarButtonItems = @[helpButton, addHostButton]; // 顺序:右边靠右的是第一个
+
+
+
+ self.navigationItem.rightBarButtonItems = @[_helpButton, _addHostButton]; // 顺序:右边靠右的是第一个
- self.navigationController.navigationBar.backgroundColor = [ThemeManager appBackgroundColor];
- // self.navigationController.navigationBar
- self.navigationController.navigationBar.titleTextAttributes = @{
- NSForegroundColorAttributeName: [ThemeManager textColor]
- };
// Set the side bar button action. When it's tapped, it'll show the sidebar.
[_settingsButton setTarget:self.revealViewController];
@@ -1379,6 +1424,8 @@ static NSMutableSet* hostList;
}
// Set the host name button action. When it's tapped, it'll show the host selection view.
+ _upButton = [[UIBarButtonItem alloc] init];
+ [self->_upButton setTitle: [LocalizationHelper localizedStringForKey: @"Select New Host"]];
[_upButton setTarget:self];
[_upButton setAction:@selector(switchToHostView)];
}
@@ -1387,8 +1434,12 @@ static NSMutableSet* hostList;
[ThemeManager setUserInterfaceStyle:UIUserInterfaceStyleUnspecified];
[super viewDidLoad];
//[OrientationHelper updateOrientationToLandscape];
-
-
+ // self.navigationController.delegate = self;
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(deviceOrientationDidChange) // handle orientation change since i made portrait mode available
+ name:UIDeviceOrientationDidChangeNotification
+ object:nil];
+
#if !TARGET_OS_TV
self.settingsExpandedInStreamView = false; // init this flag
self.revealViewController.isStreaming = false; //init this flag for rvlVC
@@ -1484,7 +1535,6 @@ static NSMutableSet* hostList;
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
-
[self updateHosts];
}
@@ -1653,16 +1703,16 @@ static NSMutableSet* hostList;
[[self revealViewController] setPrimaryViewController:self];
self.revealViewController.isStreaming = false; // tell the revealViewController streaming is finished
- [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode.
+ //[self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode.
//recordedScreenWidth = CGRectGetWidth([[UIScreen mainScreen] bounds]); // Get the screen's bounds (in points), update recorded screen width
#endif
- [self.navigationController setNavigationBarHidden:NO animated:YES];
+ [self.navigationController setNavigationBarHidden:NO animated:NO];
// Hide 1px border line
UIImage* fakeImage = [[UIImage alloc] init];
- [self.navigationController.navigationBar setShadowImage:fakeImage];
- [self.navigationController.navigationBar setBackgroundImage:fakeImage forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
+ // [self.navigationController.navigationBar setShadowImage:fakeImage];
+ // [self.navigationController.navigationBar setBackgroundImage:fakeImage forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
// Check for a pending shortcut action when appearing
[self handlePendingShortcutAction];
@@ -1707,8 +1757,9 @@ static NSMutableSet* hostList;
// for that which would normally fire beginForegroundRefresh.
self.view.backgroundColor = [ThemeManager appBackgroundColor];
-
+ [self.view addSubview:self.collectionView];
[self initHostCollection];
+ [self switchToHostView];
[self retrieveSavedHosts];
@@ -1799,7 +1850,6 @@ static NSMutableSet* hostList;
- (void)updateHosts {
Log(LOG_I, @"Updating hosts...");
- float prevEdge = -1;
@synchronized (hostList) {
// Sort the host list in alphabetical order
NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)];
@@ -1844,6 +1894,18 @@ static NSMutableSet* hostList;
// This function forces immediate decoding of the UIImage, rather
// than the default lazy decoding that results in janky scrolling.
+-(void)deviceOrientationDidChange{
+ if(self.collectionView.superview == nil) return;
+ [NSLayoutConstraint activateConstraints:@[
+ [self.collectionView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
+ [self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
+ [self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor],
+ [self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor],
+ //[self.collectionView.heightAnchor constraintEqualToConstant:_headerViewHeight]
+ ]];
+}
+
+
+ (UIImage*) loadBoxArtForCaching:(TemporaryApp*)app {
UIImage* boxArt;
@@ -1925,7 +1987,7 @@ static NSMutableSet* hostList;
[cell.subviews.firstObject removeFromSuperview]; // Remove a view that was previously added
[cell addSubview:appView];
- [self.settingsButton setEnabled:![self isIPhonePortrait]]; // update settings button after host is clicked & appview loaded
+ // [self.settingsButton setEnabled:![self isIPhonePortrait]]; // update settings button after host is clicked & appview loaded
// Shadow opacity is controlled inside UIAppView based on whether the app
// is hidden or not during the update cycle.
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:cell.bounds];
@@ -2008,7 +2070,8 @@ static NSMutableSet* hostList;
- (CGSize)getHostCardSize{
CGSize cardSize;
- cardSize.height = 0.25*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds]));
+ if([self isIPhone]) cardSize.height = 0.4*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds]));
+ else cardSize.height = 0.25*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds]));
TemporaryHost* dummyHost = [[TemporaryHost alloc] init];
HostCardView* dummyCard = [[HostCardView alloc] initWithHost:dummyHost];
cardSize.width = cardSize.height * (dummyCard.size.width/dummyCard.size.height);
@@ -2027,12 +2090,12 @@ static NSMutableSet* hostList;
[self.view addSubview:self.hostCollectionVC.view];
// 设置其布局(Auto Layout 示例)
- CGFloat hostCollectionViewPadding = 75;
+ // CGFloat hostCollectionViewPadding = 75;
self.hostCollectionVC.view.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.hostCollectionVC.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:0],
- [self.hostCollectionVC.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:hostCollectionViewPadding],
- [self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-hostCollectionViewPadding],
+ [self.hostCollectionVC.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:0],
+ [self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:0],
// [self.hostCollectionVC.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:0] //?
]];
@@ -2041,5 +2104,4 @@ static NSMutableSet* hostList;
}
-
@end
diff --git a/Limelight/ViewControllers/SWRevealViewController.h b/Limelight/ViewControllers/SWRevealViewController.h
index 00087dad..679dad0c 100755
--- a/Limelight/ViewControllers/SWRevealViewController.h
+++ b/Limelight/ViewControllers/SWRevealViewController.h
@@ -241,7 +241,8 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType)
/* The following properties are provided for further customization, they are set to default values on initialization,
you do not generally have to set them */
-@property (strong, nonatomic) UIBarButtonItem *disconnectButton;
+@property (nonatomic, strong) UIBarButtonItem* disconnectButton;
+@property (nonatomic, strong) UIBarButtonItem* moreButton;
// Defines how much of the rear or right view is shown, default is 260.
// Negative values indicate that the reveal width should be computed by substracting the full front view width,
@@ -321,6 +322,10 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType)
@property (nonatomic,assign) bool isStreaming;
@property (nonatomic,assign) bool mainFrameIsInHostView;
+- (void)buttonsInStreaming;
+- (void)buttonsNotInStreaming;
+
+
@end
diff --git a/Limelight/ViewControllers/SWRevealViewController.m b/Limelight/ViewControllers/SWRevealViewController.m
index 0e00c275..6f025e3c 100755
--- a/Limelight/ViewControllers/SWRevealViewController.m
+++ b/Limelight/ViewControllers/SWRevealViewController.m
@@ -32,6 +32,7 @@
#import "SWRevealViewController.h"
#import "LocalizationHelper.h"
#import "DataManager.h"
+#import "ThemeManager.h"
#pragma mark - StatusBar Helper Function
@@ -76,10 +77,12 @@ static CGFloat statusBarAdjustment( UIView* view )
@implementation SWRevealView{
-
+ UIView *_safeAreaPadding;
+ UIView* _separatorLine;
}
+
static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1, CGFloat max1)
{
CGFloat result = min2 + (v1-min1)*((max2-min2)/(max1-min1));
@@ -107,6 +110,7 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
[self setupRearNavView];
}
+
return self;
}
@@ -138,8 +142,11 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
- (void)setupRearNavView {
// 初始化 rearNavView
_rearNavView = [[UIView alloc] init];
+ _safeAreaPadding = [[UIView alloc] init];
_rearNavView.translatesAutoresizingMaskIntoConstraints = NO;
- _rearNavView.backgroundColor = [UIColor lightGrayColor]; // 设置背景色以便查看
+ _safeAreaPadding.translatesAutoresizingMaskIntoConstraints = NO;
+ // _rearNavView.backgroundColor = [UIColor lightGrayColor]; // 设置背景色以便查看
+ _safeAreaPadding.backgroundColor = [ThemeManager appBackgroundColor];
// NSLog(@"_c.rearViewRevealWidth: %f", _c.rearViewRevealWidth);
// _rearNavView.frame = CGRectMake(0, 0, _c.rearViewRevealWidth, 100);
@@ -148,17 +155,19 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
// 设置约束 - 这里只是一个示例,你可以根据需要调整
[self insertSubview:_rearNavView belowSubview:_frontView];
-
+ [self insertSubview:_safeAreaPadding belowSubview:_frontView];
+
CGFloat navBarHeight = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad;
[NSLayoutConstraint activateConstraints:@[
- [_rearNavView.topAnchor constraintEqualToAnchor:self.topAnchor],
+ [_rearNavView.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor constant:navBarHeight],
[_rearNavView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
[_rearNavView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
[_rearNavView.heightAnchor constraintEqualToConstant:navBarHeight]
// reserve height for navigation bar
]];
// [self setupNavigationBar];
+
}
- (void)prepareRearViewForPosition:(FrontViewPosition)newPosition
@@ -250,6 +259,17 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:shadowBounds];
_frontView.layer.shadowPath = shadowPath.CGPath;
+
+ _safeAreaPadding.hidden = self.safeAreaLayoutGuide.topAnchor == 0;
+ [NSLayoutConstraint activateConstraints:@[
+ [_safeAreaPadding.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor constant:0],
+ [_safeAreaPadding.topAnchor constraintEqualToAnchor:self.topAnchor],
+ [_safeAreaPadding.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
+ [_safeAreaPadding.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+ // reserve height for navigation bar
+ ]];
+
+ //NSLog(@"width %f", self.bounds.size.width
}
@@ -619,6 +639,8 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
@implementation SWRevealViewController
{
FrontViewPosition _panInitialFrontPosition;
+ UINavigationItem *_navItem;
+ UIView* _separatorLine;
NSMutableArray *_animationQueue;
BOOL _userInteractionStore;
UIViewController *_primaryViewController;
@@ -666,6 +688,7 @@ const int FrontViewPositionNone = 0xff;
_rearViewPosition = FrontViewPositionLeft;
_rightViewPosition = FrontViewPositionLeft;
_rearViewRevealWidth = 492.0f;
+ _rearViewRevealWidth = 400;
// _rearViewRevealOverdraw = 60.0f;
_rearViewRevealOverdraw = 0.0f;
_rearViewRevealDisplacement = 40.0f;
@@ -682,9 +705,11 @@ const int FrontViewPositionNone = 0xff;
_toggleAnimationType = SWRevealToggleAnimationTypeSpring;
_springDampingRatio = 1;
_replaceViewAnimationDuration = 0.25;
+ // _frontViewShadowRadius = 2.5f;
_frontViewShadowRadius = 2.5f;
- _frontViewShadowOffset = CGSizeMake(0.0f, 2.5f);
- _frontViewShadowOpacity = 1.0f;
+ //_frontViewShadowOffset = CGSizeMake(0.0f, 2.5f);
+ _frontViewShadowOffset = CGSizeMake(0, 0);
+ _frontViewShadowOpacity = 0;
_frontViewShadowColor = [UIColor blackColor];
_userInteractionStore = YES;
_animationQueue = [NSMutableArray array];
@@ -736,7 +761,6 @@ const int FrontViewPositionNone = 0xff;
_contentView = [[SWRevealView alloc] initWithFrame:frame controller:self];
[self setupNavigationBar];
-
// set the content view to resize along with its superview
[_contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
@@ -758,6 +782,8 @@ const int FrontViewPositionNone = 0xff;
// now set the desired initial position
[self _setFrontViewPosition:initialPosition withDuration:0.0];
+ [self setupMenuSeparator];
+
}
- (bool)isIphone{
@@ -775,9 +801,9 @@ const int FrontViewPositionNone = 0xff;
// tested on iOS17.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
// Return the supported interface orientations acoordingly
- if(self.mainFrameIsInHostView){
- if([self isIphone]) return UIInterfaceOrientationMaskLandscape; //always try to lock orientaion to landscape in mainFrameView in order to prevent bug.
- else return [self getCurrentOrientation]; //always try to lock current orientaion in mainFrameView for iPad in order to prevent bug.
+ if(!_isStreaming){
+ if([self isIphone]) return UIInterfaceOrientationMaskAll; //always try to lock orientaion to landscape in mainFrameView.
+ else return UIInterfaceOrientationMaskAll; //always try to lock current orientaion in mainFrameView for iPad in order to prevent bug.
}
//lock the orientation accordingly after streaming is started
@@ -794,6 +820,15 @@ const int FrontViewPositionNone = 0xff;
// [self setupNavigationBarConstraints];
}
+- (void)viewSafeAreaInsetsDidChange {
+ [super viewSafeAreaInsetsDidChange];
+
+}
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+
+}
+
- (void)viewDidLoad{
self.isStreaming = false; //init this flag
@@ -825,46 +860,71 @@ const int FrontViewPositionNone = 0xff;
#pragma mark - Public methods and property accessors
+- (void)willMoveToPosition{
+ _separatorLine.hidden = _frontViewPosition == FrontViewPositionLeft;
+}
+
+
+- (void)setupMenuSeparator{
+ // 分隔线
+ _separatorLine = [[UIView alloc] init];
+ _separatorLine.backgroundColor = [ThemeManager separatorColor];
+ _separatorLine.translatesAutoresizingMaskIntoConstraints = NO;
+ [_contentView.frontView addSubview:_separatorLine];
+ _separatorLine.hidden = YES;
+ /*
+ [NSLayoutConstraint activateConstraints:@[
+ [_separatorLine.trailingAnchor constraintEqualToAnchor:self.centerXAnchor constant:-10],
+ [_separatorLine.topAnchor constraintEqualToAnchor:self.topAnchor],
+ [_separatorLine.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
+ [_separatorLine.widthAnchor constraintEqualToConstant:1.0]
+ ]];
+ */
+ [NSLayoutConstraint activateConstraints:@[
+ [_separatorLine.topAnchor constraintEqualToAnchor:_contentView.topAnchor constant:0],
+
+ [_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:5],
+ [_separatorLine.trailingAnchor constraintEqualToAnchor:_contentView.frontView.leadingAnchor constant:6.5],
+ ]];
+}
+
+
- (void)setupNavigationBar {
// 创建导航栏
if (_dockedNavBar == nil) _dockedNavBar = [[UINavigationBar alloc] init];
_dockedNavBar.translatesAutoresizingMaskIntoConstraints = NO;
_dockedNavBar.userInteractionEnabled = YES;
- // 创建导航项
- UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Settings"]];
-
- // Back Button
-
- UIButton *customBackButton = [UIButton buttonWithType:UIButtonTypeSystem];
if (@available(iOS 13.0, *)) {
- [customBackButton setImage:[UIImage systemImageNamed:@"chevron.left"] forState:UIControlStateNormal];
+ UINavigationBarAppearance *navBarAppearanceStandard = [[UINavigationBarAppearance alloc] init];
+ [navBarAppearanceStandard configureWithOpaqueBackground]; // 不透明
+ navBarAppearanceStandard.backgroundColor =[ThemeManager appBackgroundColor];; // 设置你需要的背景色
+ navBarAppearanceStandard.shadowColor = nil; // 去掉底部分割线(可选)
+ navBarAppearanceStandard.titleTextAttributes = @{
+ NSForegroundColorAttributeName: [ThemeManager textColor]
+ };
+ navBarAppearanceStandard.shadowColor = [UIColor clearColor];
+ navBarAppearanceStandard.backgroundImage = nil;
+ _dockedNavBar.standardAppearance = navBarAppearanceStandard;
+ _dockedNavBar.scrollEdgeAppearance = navBarAppearanceStandard;
} else {
- // Fallback on earlier versions
+ _dockedNavBar.backgroundColor = [ThemeManager appBackgroundColor];
}
- [customBackButton setTitle:[LocalizationHelper localizedStringForKey:@"Back"] forState:UIControlStateNormal];
- customBackButton.titleLabel.font = [UIFont systemFontOfSize:19 weight:UIFontWeightRegular];
- [customBackButton addTarget:self action:@selector(foldRearView) forControlEvents:UIControlEventTouchUpInside];
- //customBackButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8); // 增加点击区域
- // customBackButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5);
- UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customBackButton];
-
- /*
- UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Back"]
- style:UIBarButtonItemStylePlain
- target:self
- action:@selector(foldRearView)];
- */
+
- navItem.leftBarButtonItem = backButtonItem;
+ // 创建导航项
+ _navItem = [[UINavigationItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Settings"]];
- _disconnectButton = [[UIBarButtonItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Disconnect"]
- style:UIBarButtonItemStylePlain
- target:self
- action:@selector(disconnectRemoteSession)];
- navItem.rightBarButtonItem = _disconnectButton;
- [_dockedNavBar setItems:@[navItem]];
+ [self setupBackButton];
+ [self setupDisconnectButton];
+ [self setupMoreButton];
+
+ // navItem.rightBarButtonItem = _disconnectButton;
+
+ [_dockedNavBar setItems:@[_navItem]];
_dockedNavBar.barTintColor = [UIColor darkGrayColor];
_dockedNavBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor]};
@@ -877,9 +937,132 @@ const int FrontViewPositionNone = 0xff;
[_dockedNavBar.leadingAnchor constraintEqualToAnchor:_contentView.rearNavView.leadingAnchor],
[_dockedNavBar.widthAnchor constraintEqualToConstant:_rearViewRevealWidth],
]];
+ NSLog(@"rearViewRevealWidth %f", _rearViewRevealWidth);
}
+
+- (void)setupBackButton{
+ // Back Button
+ UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];
+ [backButton setTarget:self];
+ [backButton setAction:@selector(foldRearView)];
+ if (@available(iOS 13.0, *)) {
+ [backButton setTitle:nil];
+ UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:23 weight:UIImageSymbolWeightMedium ];
+ UIImage *image = [[UIImage systemImageNamed:@"sidebar.left" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
+ [backButton setImage:image];
+ backButton.imageInsets = UIEdgeInsetsMake(20, 10, 0, 0);
+ } else {
+ [backButton setTitle:[LocalizationHelper localizedStringForKey:@"Back"]];
+ }
+ _navItem.leftBarButtonItem = backButton;
+}
+
+- (void)setupDisconnectButton{
+ // disconnect button
+
+ _disconnectButton = [[UIBarButtonItem alloc] init];
+ [_disconnectButton setTarget:self];
+ [_disconnectButton setAction:@selector(disconnectRemoteSession)];
+ if (@available(iOS 13.0, *)) {
+ [_disconnectButton setTitle:nil];
+ UIImage *image = [[UIImage imageNamed:@"disconnect.svg" ] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+
+ [_disconnectButton setImage:image];
+ //_disconnectButton.imageInsets = UIEdgeInsetsMake(5, 5, 5, 5);
+ _disconnectButton.tintColor = [ThemeManager appPrimaryColor];
+ } else {
+ [_disconnectButton setTitle:[LocalizationHelper localizedStringForKey:@"Disconnect"]];
+ }
+
+ /*
+ _disconnectButton = [[UIBarButtonItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Disconnect"]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(disconnectRemoteSession)];
+ */
+}
+
+- (void)setupMoreButton{
+ _moreButton = [[UIBarButtonItem alloc] init];
+
+ //[moreButton setAction:@selector(moreButtonTapped:)];
+ if (@available(iOS 13.0, *)) {
+ [_moreButton setTitle:nil];
+ UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:23 weight:UIImageSymbolWeightMedium ];
+ UIImage *image = [[UIImage systemImageNamed:@"ellipsis.circle" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
+ [_moreButton setImage:image];
+ _moreButton.imageInsets = UIEdgeInsetsMake(20, 0, 0, -10);
+ } else {
+ [_moreButton setTitle:[LocalizationHelper localizedStringForKey:@"More"]];
+ }
+
+ if (@available(iOS 14.0, *)) {
+ UIAction *action1 = [UIAction actionWithTitle:@"操作1" image:[UIImage systemImageNamed:@"doc"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
+ NSLog(@"执行操作1");
+ }];
+
+ UIAction *action2 = [UIAction actionWithTitle:@"操作2" image:[UIImage systemImageNamed:@"folder"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
+ NSLog(@"执行操作2");
+ }];
+
+ UIAction *deleteAction = [UIAction actionWithTitle:@"删除" image:[UIImage systemImageNamed:@"trash"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
+ NSLog(@"执行删除操作");
+ }];
+ deleteAction.attributes = UIMenuElementAttributesDestructive;
+ // 创建菜单
+ UIMenu *menu = [UIMenu menuWithTitle:@"" children:@[action1, action2, deleteAction]];
+ _moreButton.menu = menu;
+ }
+ else{
+ [_moreButton setTarget:self];
+ [_moreButton setAction:@selector(moreButtonTapped:)];
+ }
+ // more option button
+}
+
+- (void)moreButtonTapped:(UIBarButtonItem *)sender {
+ UIMenuItem *item1 = [[UIMenuItem alloc] initWithTitle:@"操作1" action:@selector(action1)];
+ UIMenuItem *item2 = [[UIMenuItem alloc] initWithTitle:@"操作2" action:@selector(action2)];
+
+ UIMenuController *menuController = [UIMenuController sharedMenuController];
+ [menuController setMenuItems:@[item1, item2]];
+
+ UIView *targetView = [sender valueForKey:@"view"];
+ [menuController setTargetRect:targetView.bounds inView:targetView];
+ [menuController setMenuVisible:YES animated:YES];
+
+ [self becomeFirstResponder];
+}
+
+- (BOOL)canBecomeFirstResponder {
+ return YES;
+}
+
+- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
+ if (action == @selector(action1) || action == @selector(action2)) {
+ return YES;
+ }
+ return NO;
+}
+
+- (void)action1 {
+ NSLog(@"执行操作1");
+}
+
+- (void)action2 {
+ NSLog(@"执行操作2");
+}
+
+- (void)buttonsInStreaming{
+ _navItem.rightBarButtonItems = @[_disconnectButton];
+}
+
+- (void)buttonsNotInStreaming{
+ _navItem.rightBarButtonItems = @[_moreButton];
+}
+
- (void)foldRearView{
[self revealToggleAnimated:YES];
}
@@ -889,6 +1072,19 @@ const int FrontViewPositionNone = 0xff;
[self foldRearView];
}
+-(void)deviceOrientationDidChange{
+ /*
+ if(self. == nil) return;
+ [NSLayoutConstraint activateConstraints:@[
+ [self.collectionView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
+ [self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
+ [self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor],
+ [self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor],
+ //[self.collectionView.heightAnchor constraintEqualToConstant:_headerViewHeight]
+ ]];
+ */
+}
+
- (void)setFrontViewController:(UIViewController *)frontViewController
{
[self setFrontViewController:frontViewController animated:NO];
@@ -1358,7 +1554,7 @@ const int FrontViewPositionNone = 0xff;
- (void)_handleRevealGestureStateBeganWithRecognizer:(UIPanGestureRecognizer *)recognizer
{
// we know that we will not get here unless the animationQueue is empty because the recognizer
- // delegate prevents it, however we do not want any forthcoming programatic actions to disturb
+ // delegate prevfents it, however we do not want any forthcoming programatic actions to disturb
// the gesture, so we just enqueue a dummy block to ensure any programatic acctions will be
// scheduled after the gesture is completed
[self _enqueueBlock:^{}]; // <-- dummy block
@@ -1697,6 +1893,7 @@ const int FrontViewPositionNone = 0xff;
}
_frontViewPosition = newPosition;
+ [self willMoveToPosition];
void (^deploymentCompletion)(void) =
[self _deploymentForViewController:_frontViewController inView:_contentView.frontView appear:appear disappear:disappear];
@@ -1981,6 +2178,12 @@ const int FrontViewPositionNone = 0xff;
return (id)parent;
}
+- (void)buttonsInStreaming {
+}
+
+- (void)buttonsNotInStreaming {
+}
+
@end
diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h
index 82c136cd..8119a19c 100644
--- a/Limelight/ViewControllers/SettingsViewController.h
+++ b/Limelight/ViewControllers/SettingsViewController.h
@@ -104,9 +104,11 @@
#pragma clang diagnostic pop
-- (void) saveSettings;
-+ (bool) isLandscapeNow;
+- (void)saveSettings;
++ (bool)isLandscapeNow;
- (void)updateResolutionTable;
-- (void) widget:(UISlider*)widget setEnabled:(bool)enabled;
+- (void)widget:(UISlider*)widget setEnabled:(bool)enabled;
+- (void)updateTheme;
+
@end
diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m
index 156e6b1f..c3dc1ea9 100644
--- a/Limelight/ViewControllers/SettingsViewController.m
+++ b/Limelight/ViewControllers/SettingsViewController.m
@@ -13,6 +13,7 @@
#import "TemporarySettings.h"
#import "DataManager.h"
#import "MenuSectionView.h"
+#import "ThemeManager.h"
#import
#import
@@ -181,13 +182,37 @@ CGSize resolutionTable[RESOLUTION_TABLE_SIZE];
// Add a bit of padding so the view doesn't end right at the button of the display
self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width,
[self isIPhone] ? highestViewY + 20 : parentStack.frame.size.height + [self getStandardNavBarHeight] + 20);
+ /*
+ self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
+ [NSLayoutConstraint activateConstraints:@[
+ // [self.scrollView.topAnchor constraintEqualToAnchor:],
+ [self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
+ [self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
+ [self.scrollView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
+ [self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
+ ]];
+
+ NSLog(@"settingsViewWidth: %f", self.view.bounds.size.width);
+*/
+
+
+
+ double delayInSeconds = 3;
+ // Convert the delay into a dispatch_time_t value
+ dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
+ // Perform some task after the delay
+ dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay
+ // [self updateResolutionAccordingly];
+ });
+
}
// Adjust the subviews for the safe area on the iPhone X.
- (void)viewSafeAreaInsetsDidChange {
[super viewSafeAreaInsetsDidChange];
- if (@available(iOS 11.0, *)) {
+ //if (@available(iOS 11.0, *)) {
+ if (false) { // cancel this for portrait mode
for (UIView* view in self.view.subviews) {
// HACK: The official safe area is much too large for our purposes
// so we'll just use the presence of any safe area to indicate we should
@@ -276,6 +301,7 @@ BOOL isCustomResolution(CGSize res) {
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self updateResolutionTable];
+ //[self updateTheme];
NSLog(@"Resolution table updated");
}
@@ -346,6 +372,19 @@ BOOL isCustomResolution(CGSize res) {
self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
// 可选:确保 scrollView 开启垂直滚动
self.scrollView.alwaysBounceVertical = YES;
+ self.scrollView.showsVerticalScrollIndicator = NO;
+
+ /*
+ self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
+ [NSLayoutConstraint activateConstraints:@[
+ // [self.scrollView.topAnchor constraintEqualToAnchor:],
+ [self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
+ [self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
+ [self.scrollView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
+ [self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
+ ]];
+ */
+
parentStack = [[UIStackView alloc] init];
parentStack.axis = UILayoutConstraintAxisVertical;
parentStack.spacing = 0;
@@ -366,23 +405,34 @@ BOOL isCustomResolution(CGSize res) {
if (@available(iOS 13.0, *)) {
[videoSection setSectionIcon:[UIImage systemImageNamed:@"airplayvideo"]];
} else [videoSection setSectionIcon:nil];
+ self.resolutionStack.accessibilityIdentifier = @"resolutionStack";
+ self.fpsStack.accessibilityIdentifier = @"fpsStack";
+ self.codecStack.accessibilityIdentifier = @"codecStack";
[videoSection addSubStackView:_resolutionStack];
[videoSection addSubStackView:_fpsStack];
[videoSection addSubStackView:_codecStack];
[videoSection addToParentStack:parentStack];
[videoSection setExpanded:YES];
+ //_fpsStack.userInteractionEnabled = NO;
MenuSectionView *gesturesSection = [[MenuSectionView alloc] init];
gesturesSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Gestures"];
if (@available(iOS 13.0, *)) {
[gesturesSection setSectionIcon:[UIImage systemImageNamed:@"hand.draw"]];
} else [gesturesSection setSectionIcon:nil];
+ self.keyboardToggleFingerNumStack.accessibilityIdentifier = @"keyboardToggleFingerNumStack";
+ self.slideToSettingsScreenEdgeStack.accessibilityIdentifier = @"slideToSettingsScreenEdgeStack";
+ self.slideToCmdToolScreenEdgeStack.accessibilityIdentifier = @"slideToCmdToolScreenEdgeStack";
+ self.slideToSettingsDistanceStack.accessibilityIdentifier = @"slideToSettingsDistanceStack";
[gesturesSection addSubStackView:_keyboardToggleFingerNumStack];
[gesturesSection addSubStackView:_slideToSettingsScreenEdgeStack];
[gesturesSection addSubStackView:_slideToCmdToolScreenEdgeStack];
[gesturesSection addSubStackView:_slideToSettingsDistanceStack];
+ // [gesturesSection addSubStackView:_unlockDisplayOrientationStack];
[gesturesSection addToParentStack:parentStack];
[gesturesSection setExpanded:YES];
+
+
}
@@ -445,14 +495,39 @@ BOOL isCustomResolution(CGSize res) {
[parentStackTmp removeFromSuperview];
}
+- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
+ if (gesture.state == UIGestureRecognizerStateBegan) {
+ CGPoint point = [gesture locationInView:self.view];
+ UIView *touchedView = [self.view hitTest:point withEvent:nil];
+ UIStackView* capturedStack;
+ if([touchedView isKindOfClass:[UIStackView class]]){
+ if(touchedView.accessibilityIdentifier != nil) capturedStack = (UIStackView *)touchedView;
+ }
+ else if([touchedView.superview isKindOfClass:[UIStackView class]] && touchedView.superview.accessibilityIdentifier != nil) capturedStack = (UIStackView *)touchedView.superview;
+ else NSLog(@"hit test: not setting stack captured");
+ // NSLog(@"hit test obj: %@", touchedView);
+ NSLog(@"hit test name: %@", capturedStack.accessibilityIdentifier);
+ }
+}
+
- (void)viewDidLoad {
+ //[self updateTheme];
+
+ UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
+ [self.view addGestureRecognizer:longPress];
+
+
// return;
BOOL isIPad = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
- if(isIPad) [self layoutWidgetes]; // layout for ipad tmply
-
- [self initParentStack];
- [self layoutSections];
-
+ if(isIPad){
+ //[self layoutWidgetes]; // layout for ipad tmply
+ // [self.view ]
+ for(UIView* view in self.view.subviews){
+ [view removeFromSuperview];
+ }
+ [self initParentStack];
+ [self layoutSections];
+ }
self->slideToCloseSettingsViewRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)];
@@ -1173,6 +1248,80 @@ BOOL isCustomResolution(CGSize res) {
return resolutionTable[[self.resolutionSelector selectedSegmentIndex]].width;
}
+- (UIStackView *)findFlatStackViewFrom:(UIView *)view {
+ while (view != nil) {
+ if ([view isKindOfClass:[UIStackView class]]) {
+ UIStackView *stack = (UIStackView *)view;
+ BOOL hasNestedStack = NO;
+ for (UIView *sub in stack.arrangedSubviews) {
+ if ([sub isKindOfClass:[UIStackView class]]) {
+ hasNestedStack = YES;
+ break;
+ }
+ }
+ if (!hasNestedStack) {
+ return stack;
+ }
+ }
+ view = view.superview;
+ }
+ return nil;
+}
+
+
+- (void)updateThemeForLabels:(UIView *)view {
+ for (UIView *subview in view.subviews) {
+ if ([subview isKindOfClass:[UILabel class]]) {
+ UILabel *label = (UILabel *)subview;
+ if (@available(iOS 13.0, *)) {
+ label.layer.filters = nil;
+ label.textColor = [ThemeManager textColor];
+ } else {
+ // Fallback on earlier versions
+ }
+ }
+ [self updateThemeForLabels:subview];
+ }
+}
+
+- (void)updateThemeForSelectors:(UIView *)view {
+ for (UIView *subview in view.subviews) {
+ if ([subview isKindOfClass:[UISegmentedControl class]]) {
+ UISegmentedControl *selector = (UISegmentedControl *)subview;
+ if (@available(iOS 13.0, *)) {
+ selector.selectedSegmentTintColor = [ThemeManager appSecondaryColor];
+ } else {
+ // Fallback on earlier versions
+ }
+ }
+ [self updateThemeForSelectors:subview];
+ }
+}
+
+- (void)updateThemeForSliders:(UIView *)view {
+ for (UIView *subview in view.subviews) {
+ if ([subview isKindOfClass:[UISlider class]]) {
+ UISlider *slider = (UISlider *)subview;
+ if (@available(iOS 13.0, *)) {
+ } else {
+ // Fallback on earlier versions
+ }
+ slider.tintColor = [ThemeManager appSecondaryColor];
+
+ }
+ [self updateThemeForSliders:subview];
+ }
+}
+
+
+- (void)updateTheme{
+ self.view.backgroundColor = [ThemeManager appBackgroundColor];
+ [self updateThemeForLabels:self.view];
+ [self updateThemeForSelectors:self.view];
+ [self updateThemeForSliders:self.view];
+}
+
+
- (void) saveSettings {
DataManager* dataMan = [[DataManager alloc] init];
NSInteger framerate = [self getChosenFrameRate];
diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m
index b4f1aa8d..8d0684d8 100644
--- a/Limelight/ViewControllers/StreamFrameViewController.m
+++ b/Limelight/ViewControllers/StreamFrameViewController.m
@@ -323,8 +323,6 @@
dispatch_resume(timer);
- // 防止循环引用(虽然这里用__block已经足够)
- __weak typeof(alert) weakAlert = alert;
}