- host card actions including long press
- add host button
This commit is contained in:
TrueZhuanjia
2025-06-01 04:06:06 +08:00
parent 6ae3beb2a5
commit 049034e5a9
14 changed files with 628 additions and 383 deletions
+9 -8
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -12,7 +12,7 @@
<objects>
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
<rect key="frame" x="0.0" y="0.0" width="834" height="1120"/>
<rect key="frame" x="0.0" y="0.0" width="834" height="1136"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
@@ -41,6 +41,7 @@
<barButtonItem key="rightBarButtonItem" id="KDy-JC-2sU"/>
</navigationItem>
<connections>
<outlet property="navigationItem" destination="pSu-bl-gL9" id="Xni-ne-p40"/>
<outlet property="settingsButton" destination="mSL-ru-nRm" id="NRf-lv-vlh"/>
<outlet property="upButton" destination="KDy-JC-2sU" id="tXB-Rc-IvJ"/>
<segue destination="OIm-0n-i9v" kind="push" identifier="createStreamFrame" id="7gN-E7-Ips"/>
@@ -868,7 +869,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="YRO-Lg-RCg"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="hGs-BR-t4b">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
<rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
@@ -908,7 +909,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="vu8-3s-HlY"/>
</layoutGuides>
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="SMn-1j-R3I">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
<rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.3333357871" green="0.33332890269999998" blue="0.33333355190000002" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</view>
@@ -930,7 +931,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="YZj-An-sqS"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="le1-tU-NEp">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
<rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="N0D-dj-EuF">
@@ -1270,13 +1271,13 @@ ICAgICAgICAgICAgICA
<image name="SquaresArrowUp" width="40" height="40"/>
<image name="Trash" width="40" height="40"/>
<systemColor name="secondaryLabelColor">
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="viewFlipsideBackgroundColor">
<color red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+14
View File
@@ -0,0 +1,14 @@
//
// FixedTintImageView.h
// Moonlight-ZWM
//
// Created by True砖家 on 2025.6.1.
// Copyright © 2025 True砖家 @ Bilibili. All rights reserved.
//
// MenuSectionView.m
@interface FixedTintImageView : UIImageView
@end
@interface FixedTintButton : UIButton
@end
+61
View File
@@ -0,0 +1,61 @@
//
// FixedTintImageView.m
// Moonlight-ZWM
//
// Created by Weimin on 2025/6/1.
// Copyright © 2025 Moonlight Game Streaming Project. All rights reserved.
//
#import "FixedTintImageView.h"
@interface FixedTintButton()
@property (nonatomic, strong) UIColor *fixedTintColor;
@end
@implementation FixedTintButton
- (void)tintColorDidChange {
[super tintColorDidChange];
// 强制 tint 保持固定颜色
if (self.fixedTintColor) {
[self setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
self.tintColor = self.fixedTintColor;
}
}
- (void)setTintColor:(UIColor *)tintColor {
_fixedTintColor = tintColor;
[super setTintColor:tintColor];
}
@end
@interface FixedTintImageView ()
@property (nonatomic, strong) UIColor *fixedTintColor;
@end
@implementation FixedTintImageView
- (instancetype)initWithImage:(UIImage *)image {
self = [super initWithImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
if (self) {
// _fixedTintColor = [UIColor systemBlueColor]; // 默认颜色
if(_fixedTintColor != nil) [super setTintColor:_fixedTintColor];
}
return self;
}
- (void)setTintColor:(UIColor *)tintColor {
if(_fixedTintColor == nil && tintColor != nil) _fixedTintColor = tintColor;
if(tintColor != nil) [super setTintColor:tintColor];
}
- (void)tintColorDidChange {
// 保持你固定的颜色,忽略系统的暗淡变更
if(_fixedTintColor != nil) [super setTintColor:_fixedTintColor];
}
@end
+7 -6
View File
@@ -10,18 +10,19 @@
#import <UIKit/UIKit.h>
#import "TemporaryHost.h"
@protocol HostCardButtonActionDelegate <NSObject>
- (void)leftButtonTappedForHost:(TemporaryHost *)host;
- (void)rightButtonTappedForHost:(TemporaryHost *)host;
@protocol HostCardActionDelegate <NSObject>
- (void)appButtonTappedForHost:(TemporaryHost *)host;
- (void)launchButtonTappedForHost:(TemporaryHost *)host;
- (void)wakeupButtonTappedForHost:(TemporaryHost *)host;
- (void)pairButtonTappedForHost:(TemporaryHost *)host;
- (void)hostCardLongPressed:(TemporaryHost *)host view:(UIView *)view;
@end
@interface HostCardView : UIView
@interface HostCardView : UIView <UIContextMenuInteractionDelegate>
@property (nonatomic, assign) CGFloat sizeFactor;
@property (nonatomic, readonly) CGSize size;
@property (nonatomic, weak) id<HostCardButtonActionDelegate> delegate; // Delegate property
@property (nonatomic, weak) id<HostCardActionDelegate> delegate; // Delegate property
- (void)resizeBySizeFactor:(CGFloat)factor;
- (id) initWithHost:(TemporaryHost*)host;
+216 -216
View File
@@ -9,6 +9,8 @@
#import "HostCardView.h"
#import "LocalizationHelper.h"
#import "ThemeManager.h"
#import "FixedTintImageView.h"
@interface HostCardView ()
@@ -17,10 +19,11 @@
@property (nonatomic, strong) UILabel *hostNameLabel;
@property (nonatomic, strong) UIImageView *statusIcon;
@property (nonatomic, strong) UILabel *statusLabel;
@property (nonatomic, strong) UIButton *leftButton;
@property (nonatomic, strong) UIButton *rightButton;
@property (nonatomic, strong) UIButton *appButton;
@property (nonatomic, strong) UIButton *launchButton;
@property (nonatomic, strong) UIButton *pairButton;
@property (nonatomic, strong) UIButton *settingsButton;
@property (nonatomic, strong) UIButton *wakeupButton;
@property (nonatomic, strong) UIButton *transparentButton;
@property (nonatomic, strong) NSLayoutConstraint *widthConstraint;
@property (nonatomic, strong) NSLayoutConstraint *heightConstraint;
@property (nonatomic, strong) UIView *separatorLine;
@@ -41,7 +44,7 @@
UIColor *defaultBlue;
UIColor *defaultGreen;
CAGradientLayer *backgroundLayer;
bool longPressFired;
}
static const float REFRESH_CYCLE = 2.0f;
@@ -50,12 +53,25 @@ static const float REFRESH_CYCLE = 2.0f;
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
longPressFired = false;
computerIconMonitorCenterYOffset = -3.3*_sizeFactor;
iconAndButtonSpacing = 37*_sizeFactor;
buttonHeight = 40*_sizeFactor;
defaultBlue = [ThemeManager appPrimaryColor];
defaultGreen = [UIColor colorWithRed:52.0/255.0 green:199.0/255.0 blue:89.0/255.0 alpha:1.0];
// self.userIterfaceStyle = UIUserInterfaceStyleLight;
// self.userIterfaceStyle = UIUserInterfaceStyleLight
if (@available(iOS 13.0, *)) {
NSLog(@"ttesttttt");
UIContextMenuInteraction* longPressInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
[self addInteraction:longPressInteraction];
self.userInteractionEnabled = YES;
}
else
{
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(hostLongClicked:)];
[self addGestureRecognizer:longPressRecognizer];
}
[self createBackgroundLayer];
[self setupUI];
}
@@ -69,6 +85,7 @@ static const float REFRESH_CYCLE = 2.0f;
// Use UIContextMenuInteraction on iOS 13.0+ and a standard UILongPressGestureRecognizer
// for tvOS devices and iOS prior to 13.0.
return self;
}
@@ -91,28 +108,62 @@ static const float REFRESH_CYCLE = 2.0f;
return self;
}
- (void)leftButtonTapped{
- (void)appButtonTapped{
if(longPressFired){
longPressFired = false;
return;
}
NSLog(@"self.delegate: %lu", (uintptr_t)self.delegate);
if ([self.delegate respondsToSelector:@selector(leftButtonTappedForHost:)]) {
[self.delegate leftButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to leftButtonTappedForHost:");
if ([self.delegate respondsToSelector:@selector(appButtonTappedForHost:)]) {
[self.delegate appButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to appButtonTappedForHost:");
}
- (void)rightButtonTapped{
if ([self.delegate respondsToSelector:@selector(rightButtonTappedForHost:)]) {
[self.delegate rightButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to rightButtonTappedForHost:");
- (void)launchButtonTapped{
if(longPressFired){
longPressFired = false;
return;
}
if ([self.delegate respondsToSelector:@selector(launchButtonTappedForHost:)]) {
[self.delegate launchButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to launchButtonTappedForHost:");
}
- (void)wakeupButtonTapped{
if(longPressFired){
longPressFired = false;
return;
}
if ([self.delegate respondsToSelector:@selector(wakeupButtonTappedForHost:)]) {
[self.delegate wakeupButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to launchButtonTappedForHost:");
}
-(void)pairButtonTapped{
NSLog(@"pairButtonTapped testtestttttt");
if(longPressFired){
longPressFired = false;
return;
}
if ([self.delegate respondsToSelector:@selector(pairButtonTappedForHost:)]) {
[self.delegate pairButtonTappedForHost:_host];
} else NSLog(@"Delegate not set or does not respond to rightButtonTappedForHost:");
} else NSLog(@"Delegate not set or does not respond to pairButtonTappedForHost:");
}
- (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];
} else NSLog(@"Delegate not set or does not respond to pairButtonTappedForHost:");
return nil;
}
- (void)resizeBySizeFactor:(CGFloat)factor{
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
self.sizeFactor = factor;
@@ -120,6 +171,7 @@ static const float REFRESH_CYCLE = 2.0f;
}
- (void)setupUI {
self.userInteractionEnabled = YES;
self.backgroundColor = [ThemeManager widgetBackgroundColor]; // theme
self.layer.cornerRadius = 16;
self.cardContentpadding = 13 * _sizeFactor;
@@ -128,22 +180,22 @@ static const float REFRESH_CYCLE = 2.0f;
CGFloat appButtonWidth = 100*_sizeFactor;
CGFloat launchButtonWidth = 120*_sizeFactor;
/*
NSLayoutConstraint *topAnchorConstraint;
topAnchorConstraint = [self.topAnchor constraintEqualToAnchor:self.superview.topAnchor constant:500];
topAnchorConstraint.active = YES;
*/
NSLayoutConstraint *topAnchorConstraint;
topAnchorConstraint = [self.topAnchor constraintEqualToAnchor:self.superview.topAnchor constant:500];
topAnchorConstraint.active = YES;
*/
_heightConstraint = [self.heightAnchor constraintEqualToConstant:300];
_heightConstraint.active = YES;
_widthConstraint = [self.widthAnchor constraintEqualToConstant:300];
_widthConstraint.active = YES;
// 图标背景
self.iconBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(_cardContentpadding, _cardContentpadding, 80*_sizeFactor, 80*_sizeFactor)];
self.iconBackgroundView.backgroundColor = defaultBlue;
self.iconBackgroundView.layer.cornerRadius = 20*_sizeFactor;
[self addSubview:self.iconBackgroundView];
// 图标图片
self.hostIconView = [[UIImageView alloc] init];
self.hostIconView.translatesAutoresizingMaskIntoConstraints = NO;
@@ -167,7 +219,7 @@ static const float REFRESH_CYCLE = 2.0f;
]];
// [self.iconBackgroundView layoutIfNeeded];
// [self.iconImageView layoutIfNeeded];
//spinner
_hostSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
_hostSpinner.userInteractionEnabled = NO;
@@ -181,7 +233,7 @@ static const float REFRESH_CYCLE = 2.0f;
_hostSpinner.transform = CGAffineTransformMakeScale(_sizeFactor, _sizeFactor);
[_hostSpinner stopAnimating];
// [_hostSpinner startAnimating];
// lockIcon
lockIconView =[[UIImageView alloc] init];
@@ -200,22 +252,22 @@ static const float REFRESH_CYCLE = 2.0f;
[lockIconView.heightAnchor constraintEqualToConstant:22*_sizeFactor]
]];
lockIconView.hidden = true;
// 设备名
self.hostNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(_cardContentpadding+_iconBackgroundView.frame.size.width+20*_sizeFactor, _cardContentpadding+_iconBackgroundView.frame.size.height/10, 300*_sizeFactor, 30*_sizeFactor)];
self.hostNameLabel.numberOfLines = 1;
self.hostNameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
self.hostIconView.translatesAutoresizingMaskIntoConstraints = NO;
self.hostNameLabel.text = @"RazerBlade 16";
self.hostNameLabel.textColor = [UIColor whiteColor]; //theme
self.hostNameLabel.font = [UIFont boldSystemFontOfSize:20*_sizeFactor];
[self addSubview:self.hostNameLabel];
// 在线状态图标
self.statusIcon = [[UIImageView alloc] initWithFrame:CGRectMake(180, 70, 20*_sizeFactor, 20*_sizeFactor)];
self.statusIcon = [[FixedTintImageView alloc] initWithFrame:CGRectMake(180, 70, 20*_sizeFactor, 20*_sizeFactor)];
self.statusIcon.contentMode = UIViewContentModeScaleAspectFit;
self.statusIcon.translatesAutoresizingMaskIntoConstraints = NO;
if (@available(iOS 13.0, *)) {
@@ -224,15 +276,15 @@ static const float REFRESH_CYCLE = 2.0f;
// Fallback on earlier versions
}
self.statusIcon.tintColor = defaultGreen;
[self addSubview:self.statusIcon];
[NSLayoutConstraint activateConstraints:@[
[self.statusIcon.leadingAnchor constraintEqualToAnchor:self.hostNameLabel.leadingAnchor],
[self.statusIcon.topAnchor constraintEqualToAnchor:self.hostNameLabel.bottomAnchor constant:4*_sizeFactor],
[self.statusIcon.widthAnchor constraintEqualToConstant:19*_sizeFactor]
]];
// 在线文字
self.statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(205, 68, 100, 24)];
self.statusLabel.translatesAutoresizingMaskIntoConstraints = NO;
@@ -245,65 +297,53 @@ static const float REFRESH_CYCLE = 2.0f;
[self.statusLabel.leadingAnchor constraintEqualToAnchor:self.statusIcon.trailingAnchor constant:3*_sizeFactor],
[self.statusLabel.centerYAnchor constraintEqualToAnchor:self.statusIcon.centerYAnchor constant:0],
]];
// 设置按钮
/*
self.settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.settingsButton.frame = CGRectMake(self.bounds.size.width - 40, 20, 24, 24);
if (@available(iOS 13.0, *)) {
[self.settingsButton setImage:[UIImage systemImageNamed:@"gearshape"] forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
self.settingsButton.tintColor = [UIColor lightGrayColor];
[self addSubview:self.settingsButton];
*/
// 启动应用按钮
self.leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.leftButton.translatesAutoresizingMaskIntoConstraints = NO;
self.leftButton.frame = CGRectMake(20, 200, 150, buttonHeight);
[self.leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal];
[self.leftButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal]; //theme
self.leftButton.titleLabel.font = [UIFont systemFontOfSize:16*_sizeFactor];
[self.leftButton addTarget:self action:@selector(leftButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.leftButton];
self.appButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.appButton.translatesAutoresizingMaskIntoConstraints = NO;
self.appButton.frame = CGRectMake(20, 200, 150, buttonHeight);
[self.appButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal];
[self.appButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal]; //theme
self.appButton.titleLabel.font = [UIFont systemFontOfSize:16*_sizeFactor];
[self.appButton addTarget:self action:@selector(appButtonTapped) forControlEvents:UIControlEventPrimaryActionTriggered];
[self addSubview:self.appButton];
[NSLayoutConstraint activateConstraints:@[
[self.leftButton.leadingAnchor constraintEqualToAnchor:self.iconBackgroundView.leadingAnchor constant:0],
[self.leftButton.topAnchor constraintEqualToAnchor:self.iconBackgroundView.bottomAnchor constant:iconAndButtonSpacing],
[self.leftButton.widthAnchor constraintEqualToConstant:appButtonWidth],
[self.leftButton.heightAnchor constraintEqualToConstant:buttonHeight],
[self.appButton.leadingAnchor constraintEqualToAnchor:self.iconBackgroundView.leadingAnchor constant:0],
[self.appButton.topAnchor constraintEqualToAnchor:self.iconBackgroundView.bottomAnchor constant:iconAndButtonSpacing],
[self.appButton.widthAnchor constraintEqualToConstant:appButtonWidth],
[self.appButton.heightAnchor constraintEqualToConstant:buttonHeight],
// [self.launchButton.titleLabel.leadingAnchor constraintEqualToAnchor:self.launchButton.imageView.trailingAnchor constant:3*_sizeFactor]
]];
// 开始串流按钮
self.rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.rightButton.translatesAutoresizingMaskIntoConstraints = NO;
self.rightButton.frame = CGRectMake(0, 0, 150, 50);
self.rightButton.backgroundColor = defaultBlue;
self.rightButton.layer.cornerRadius = 10;
[self.rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal];
[self.rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // theme
self.rightButton.titleLabel.font = [UIFont boldSystemFontOfSize:16*_sizeFactor];
self.rightButton.tintColor = [UIColor whiteColor];
[self.rightButton addTarget:self action:@selector(rightButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.rightButton];
self.launchButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.launchButton.translatesAutoresizingMaskIntoConstraints = NO;
self.launchButton.frame = CGRectMake(0, 0, 150, 50);
self.launchButton.backgroundColor = defaultBlue;
self.launchButton.layer.cornerRadius = 10;
[self.launchButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal];
[self.launchButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // theme
self.launchButton.titleLabel.font = [UIFont boldSystemFontOfSize:16*_sizeFactor];
self.launchButton.tintColor = [UIColor whiteColor];
[self.launchButton addTarget:self action:@selector(launchButtonTapped) forControlEvents:UIControlEventPrimaryActionTriggered];
[self addSubview:self.launchButton];
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.rightButton.frame.size.height/4*_sizeFactor];
[self.rightButton setImage:[UIImage systemImageNamed:@"play.fill" withConfiguration:config] forState:UIControlStateNormal];
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.launchButton.frame.size.height*_sizeFactor];
[self.launchButton setImage:[UIImage systemImageNamed:@"play.fill" withConfiguration:config] forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
[NSLayoutConstraint activateConstraints:@[
[self.rightButton.leadingAnchor constraintEqualToAnchor:self.leftButton.trailingAnchor constant:15*_sizeFactor],
[self.rightButton.centerYAnchor constraintEqualToAnchor:self.leftButton.centerYAnchor constant:0],
[self.rightButton.widthAnchor constraintEqualToConstant:launchButtonWidth],
[self.rightButton.heightAnchor constraintEqualToConstant:buttonHeight],
[self.launchButton.leadingAnchor constraintEqualToAnchor:self.appButton.trailingAnchor constant:15*_sizeFactor],
[self.launchButton.centerYAnchor constraintEqualToAnchor:self.appButton.centerYAnchor constant:0],
[self.launchButton.widthAnchor constraintEqualToConstant:launchButtonWidth],
[self.launchButton.heightAnchor constraintEqualToConstant:buttonHeight],
// [self.launchButton.titleLabel.leadingAnchor constraintEqualToAnchor:self.launchButton.imageView.trailingAnchor constant:3*_sizeFactor]
]];
@@ -316,10 +356,6 @@ static const float REFRESH_CYCLE = 2.0f;
[self.pairButton setTitle:[LocalizationHelper localizedStringForKey:@" Pair with PIN"] forState:UIControlStateNormal];
[self.pairButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
self.pairButton.titleLabel.font = [UIFont boldSystemFontOfSize:16*_sizeFactor];
[self.pairButton addTarget:self action:@selector(pairButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.pairButton];
// self.launchButton.imageEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.pairButton.frame.size.height/3.5*_sizeFactor weight:UIImageSymbolWeightBold];
UIImage *templateImage = [UIImage systemImageNamed:@"lock.open.fill" withConfiguration:config];
@@ -328,9 +364,12 @@ static const float REFRESH_CYCLE = 2.0f;
} else {
// Fallback on earlier versions
}
_pairButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
[_pairButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
self.pairButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
[self.pairButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
[self.pairButton addTarget:self action:@selector(pairButtonTapped) forControlEvents:UIControlEventPrimaryActionTriggered];
[self addSubview:self.pairButton];
[NSLayoutConstraint activateConstraints:@[
[self.pairButton.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:_cardContentpadding],
[self.pairButton.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-_cardContentpadding],
@@ -338,7 +377,31 @@ static const float REFRESH_CYCLE = 2.0f;
// [self.pairButton.widthAnchor constraintEqualToConstant:launchButtonWidth],
[self.pairButton.heightAnchor constraintEqualToConstant:buttonHeight],
]];
// 唤醒按钮
self.wakeupButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.wakeupButton.translatesAutoresizingMaskIntoConstraints = NO;
self.wakeupButton.frame = CGRectMake(0, 0, 150, 50);
self.wakeupButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
self.wakeupButton.layer.cornerRadius = 10;
[self.wakeupButton setTitle:[LocalizationHelper localizedStringForKey:@" Wake-on-LAN"] forState:UIControlStateNormal];
[self.wakeupButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
self.wakeupButton.titleLabel.font = [UIFont boldSystemFontOfSize:16*_sizeFactor];
[self.wakeupButton addTarget:self action:@selector(wakeupButtonTapped) forControlEvents:UIControlEventPrimaryActionTriggered];
[self addSubview:self.wakeupButton];
[NSLayoutConstraint activateConstraints:@[
[self.wakeupButton.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:_cardContentpadding],
[self.wakeupButton.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-_cardContentpadding],
[self.wakeupButton.topAnchor constraintEqualToAnchor:self.iconBackgroundView.bottomAnchor constant:iconAndButtonSpacing],
// [self.pairButton.widthAnchor constraintEqualToConstant:launchButtonWidth],
[self.wakeupButton.heightAnchor constraintEqualToConstant:buttonHeight],
]];
//分隔线
_separatorLine = [[UIView alloc] init];
@@ -350,22 +413,33 @@ static const float REFRESH_CYCLE = 2.0f;
[_separatorLine.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-_cardContentpadding],
[_separatorLine.centerYAnchor constraintEqualToAnchor:_iconBackgroundView.bottomAnchor constant: iconAndButtonSpacing/2],
[_separatorLine.heightAnchor constraintEqualToConstant:1.0/UIScreen.mainScreen.scale]
// [self.launchButton.titleLabel.leadingAnchor constraintEqualToAnchor:self.launchButton.imageView.trailingAnchor constant:3*_sizeFactor]
]];
// [self layoutSubviews];
// [self layoutIfNeeded];
// 透明按钮
self.transparentButton = [UIButton buttonWithType:UIButtonTypeCustom];
// self.transparentButton.frame = CGRectMake(50, 100, 100, 100); // 设置点击区域
self.transparentButton.translatesAutoresizingMaskIntoConstraints = NO;
// 设置透明背景和无内容
self.transparentButton.backgroundColor = [UIColor clearColor];
[self.transparentButton setTitle:@"" forState:UIControlStateNormal];
[self.transparentButton setImage:nil forState:UIControlStateNormal];
[self.transparentButton addTarget:self action:@selector(appButtonTapped) forControlEvents:UIControlEventPrimaryActionTriggered];
[self addSubview:self.transparentButton];
[NSLayoutConstraint activateConstraints:@[
[self.transparentButton.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:0],
[self.transparentButton.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:0],
[self.transparentButton.topAnchor constraintEqualToAnchor:self.topAnchor constant:0],
[self.transparentButton.bottomAnchor constraintEqualToAnchor:self.separatorLine.topAnchor],
]];
_widthConstraint.constant = _cardContentpadding*2 + appButtonWidth + 15*_sizeFactor + launchButtonWidth;
_heightConstraint.constant = _cardContentpadding*2 + _iconBackgroundView.frame.size.height + iconAndButtonSpacing + buttonHeight + 1;
_size = CGSizeMake(_widthConstraint.constant, _heightConstraint.constant);
// standard size: 261 * 184
[self updateTheme:ThemeManager.userInterfaceStyle];
// [self updateContentsForHost:_host];
// [self updateTheme:UIUserInterfaceStyleLight];
}
- (void)createBackgroundLayer{
@@ -379,11 +453,11 @@ static const float REFRESH_CYCLE = 2.0f;
(__bridge id)[UIColor clearColor].CGColor,
(__bridge id)gradientColorRef
];
backgroundLayer.locations = @[@0, @0.18, @0.5, @1];
backgroundLayer.startPoint = CGPointMake(0.25, 0.5);
backgroundLayer.endPoint = CGPointMake(0.75, 0.5);
CGAffineTransform transform = CGAffineTransformMake(-1.01, -1, 1, -3.67, 0.5, 2.83);
backgroundLayer.transform = CATransform3DMakeAffineTransform(transform);
[self.layer insertSublayer:backgroundLayer atIndex:0];
@@ -396,40 +470,22 @@ static const float REFRESH_CYCLE = 2.0f;
[self updateContentsForHost:_host]; // quick update before looping
}
- (void)tintAdjustmentModeDidChange {
// [super tintAdjustmentModeDidChange];
NSLog(@"tintChanged........");
self.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
}
- (void)updateTheme:(UIUserInterfaceStyle)userIterfaceStyle{
self.backgroundColor = [ThemeManager widgetBackgroundColor];
_hostNameLabel.textColor = [ThemeManager textColor];
[_leftButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal];
[_appButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal];
_separatorLine.backgroundColor = [ThemeManager separatorColor];
backgroundLayer.hidden = NO;
/*
switch (userIterfaceStyle) {
case UIUserInterfaceStyleDark:
_hostNameLabel.textColor = [ThemeManager textColorDark];
[_leftButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal];
_separatorLine.backgroundColor = [ThemeManager separatorColorDark];
// [_rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
//self.backgroundColor = [ThemeManager widgetBackgroundColorDark];
backgroundLayer.hidden = NO;
break;
case UIUserInterfaceStyleLight:
_hostNameLabel.textColor = [ThemeManager textColorLight];
[_leftButton setTitleColor:[ThemeManager appPrimaryColor] forState:UIControlStateNormal];
_separatorLine.backgroundColor = [ThemeManager separatorColorLight];
// [_rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
// self.backgroundColor = [ThemeManager widgetBackgroundColorLight];
backgroundLayer.hidden = NO;
break;
default:break;
}
*/
[self updateContentsForHost:_host];
}
- (void)didMoveToSuperview {
// Start our update loop when we are added to our cell
if (self.superview != nil && _host != nil) {
@@ -440,7 +496,7 @@ static const float REFRESH_CYCLE = 2.0f;
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if (@available(iOS 13.0, *)) {
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
[self updateTheme:self.traitCollection.userInterfaceStyle];
@@ -456,7 +512,7 @@ static const float REFRESH_CYCLE = 2.0f;
if (self.superview == nil) {
return;
}
[self updateContentsForHost:_host];
// Queue the next refresh cycle
@@ -465,12 +521,7 @@ static const float REFRESH_CYCLE = 2.0f;
- (void) updateContentsForHost:(TemporaryHost*)host {
_hostNameLabel.text = host.name;
// self.hostNameLabel.text = @"RazerBlade 16 testttttettest";
backgroundLayer.hidden = !(host.state == StateOnline && host.pairState == PairStatePaired);
switch (host.state) {
case StateOnline:
@@ -485,55 +536,38 @@ static const float REFRESH_CYCLE = 2.0f;
// Fallback on earlier versions
}
_hostIconView.tintColor = [UIColor whiteColor];
_appButton.titleLabel.font = [UIFont systemFontOfSize:16*_sizeFactor];
if(host.pairState == PairStatePaired){
_iconBackgroundView.backgroundColor = defaultBlue;
lockIconView.hidden = YES;
[_leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal];
[_rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal];
[_leftButton setEnabled:YES];
[_rightButton setEnabled:YES];
_leftButton.hidden = NO;
_rightButton.hidden = NO;
[_appButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal];
[_launchButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal];
[_appButton setEnabled:YES];
[_launchButton setEnabled:YES];
_appButton.hidden = NO;
_launchButton.hidden = NO;
_pairButton.hidden = YES;
[_leftButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
_wakeupButton.hidden = YES;
[_appButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.rightButton.frame.size.height/4*_sizeFactor];
[self.rightButton setImage:[UIImage systemImageNamed:@"play.fill" withConfiguration:config] forState:UIControlStateNormal];
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.launchButton.frame.size.height/4*_sizeFactor];
[self.launchButton setImage:[UIImage systemImageNamed:@"play.fill" withConfiguration:config] forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
_rightButton.backgroundColor = defaultBlue;
[_rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // theme
_launchButton.backgroundColor = defaultBlue;
[_launchButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // theme
}
else {
_iconBackgroundView.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
lockIconView.hidden = NO;
[_leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal];
[_rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal];
[_leftButton setEnabled:YES];
[_rightButton setEnabled:YES];
_leftButton.hidden = YES;
_rightButton.hidden = YES;
_appButton.hidden = YES;
_launchButton.hidden = YES;
_pairButton.hidden = NO;
[_leftButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.rightButton.frame.size.height/4*_sizeFactor];
[self.rightButton setImage:[UIImage systemImageNamed:@"play.fill" withConfiguration:config] forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
_rightButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
[_rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // theme
_wakeupButton.hidden = YES;
}
break;
case StateOffline:
[_hostSpinner stopAnimating];
@@ -549,27 +583,22 @@ static const float REFRESH_CYCLE = 2.0f;
}
_hostIconView.tintColor = [ThemeManager lowProfileGray];
lockIconView.hidden = YES;
[_leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Test network"] forState:UIControlStateNormal];
[_rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Wakeup"] forState:UIControlStateNormal];
[_leftButton setEnabled:YES];
[_rightButton setEnabled:YES];
_leftButton.hidden = NO;
_rightButton.hidden = NO;
_appButton.hidden = YES;
_launchButton.hidden = YES;
_pairButton.hidden = YES;
[_leftButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
_wakeupButton.hidden = NO;
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.rightButton.frame.size.height/3.5*_sizeFactor weight:UIImageSymbolWeightBold];
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.wakeupButton.frame.size.height/3.2*_sizeFactor weight:UIImageSymbolWeightBold];
UIImage *templateImage = [UIImage systemImageNamed:@"power" withConfiguration:config];
UIImage *coloredImage = [templateImage imageWithTintColor:defaultBlue renderingMode:UIImageRenderingModeAlwaysOriginal];
[self.rightButton setImage:coloredImage forState:UIControlStateNormal];
[self.wakeupButton setImage:coloredImage forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
_rightButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
[_rightButton setTitleColor:defaultBlue forState:UIControlStateNormal]; // theme
self.wakeupButton.backgroundColor = [ThemeManager appPrimaryColorWithAlpha];
[self.wakeupButton setTitleColor:defaultBlue forState:UIControlStateNormal];
break;
case StateUnknown:
_hostSpinner.color = [UIColor whiteColor];
@@ -587,55 +616,26 @@ static const float REFRESH_CYCLE = 2.0f;
// _hostIconView.tintColor = [UIColor lowProfileGray];
_hostIconView.tintColor = defaultBlue;
lockIconView.hidden = YES;
[_leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Test network"] forState:UIControlStateNormal];
[_rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Wakeup"] forState:UIControlStateNormal];
[_leftButton setEnabled:NO];
[_rightButton setEnabled:NO];
_leftButton.hidden = NO;
_rightButton.hidden = NO;
_appButton.hidden = YES;
_launchButton.hidden = YES;
_pairButton.hidden = YES;
_wakeupButton.hidden = NO;
[_leftButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal]; // theme
[_wakeupButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal]; // theme
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.rightButton.frame.size.height/3.5*_sizeFactor weight:UIImageSymbolWeightBold];
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:self.wakeupButton.frame.size.height/3.2*_sizeFactor weight:UIImageSymbolWeightBold];
UIImage *templateImage = [UIImage systemImageNamed:@"power" withConfiguration:config];
UIImage *coloredImage = [templateImage imageWithTintColor:[ThemeManager textColorGray] renderingMode:UIImageRenderingModeAlwaysOriginal];
[self.rightButton setImage:coloredImage forState:UIControlStateNormal];
[self.wakeupButton setImage:coloredImage forState:UIControlStateNormal];
} else {
// Fallback on earlier versions
}
_rightButton.backgroundColor = [[ThemeManager textColorGray] colorWithAlphaComponent:0.2];
[_rightButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal]; // theme
self.wakeupButton.backgroundColor = [[ThemeManager textColorGray] colorWithAlphaComponent:0.2];
[self.wakeupButton setTitleColor:[ThemeManager textColorGray] forState:UIControlStateNormal];
break;
default:break;
}
/*
if (host.state == StateOnline) {
[_hostSpinner stopAnimating];
lockIconView.hidden = ! (host.pairState == PairStateUnpaired);
if (host.pairState == PairStateUnpaired) {
}
else {
}
}
else if (host.state == StateOffline) {
[_hostSpinner stopAnimating];
}
else {
[_hostSpinner startAnimating];
}
*/
}
@end
+53 -88
View File
@@ -10,123 +10,88 @@
@implementation ThemeManager
static UIUserInterfaceStyle _userInterfaceStyle = UIUserInterfaceStyleLight;
static UIUserInterfaceStyle _privateUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
static UIUserInterfaceStyle _userInterfaceStyle;
+ (UIColor *)getUIStyle{
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 getUIStyle];
return _userInterfaceStyle;
}
+ (void)setUserInterfaceStyle:(UIUserInterfaceStyle)style {
_userInterfaceStyle = style;
_privateUserInterfaceStyle = style;
[ThemeManager getUIStyle];
}
+ (UIColor *)appBackgroundColor {
if (@available(iOS 13.0, *)) {
return [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
UIUserInterfaceStyle style = self.userInterfaceStyle;
if (style == UIUserInterfaceStyleUnspecified) {
// 跟随系统
style = traitCollection.userInterfaceStyle;
}
switch (style) {
case UIUserInterfaceStyleLight:
return [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0];
case UIUserInterfaceStyleDark:
default:
return [UIColor colorWithRed:28.0/255.0 green:28.0/255.0 blue:30.0/255.0 alpha:1.0];
}
}];
} else {
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];
case UIUserInterfaceStyleDark:
default:
return [UIColor colorWithRed:28.0/255.0 green:28.0/255.0 blue:30.0/255.0 alpha:1.0];
}
[ThemeManager getUIStyle];
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];
break;
}
}
+ (UIColor *)widgetBackgroundColor {
if (@available(iOS 13.0, *)) {
return [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
UIUserInterfaceStyle style = self.userInterfaceStyle;
if (style == UIUserInterfaceStyleUnspecified) {
// 跟随系统
style = traitCollection.userInterfaceStyle;
}
switch (style) {
case UIUserInterfaceStyleLight:
return [UIColor whiteColor];
case UIUserInterfaceStyleDark:
default:
return [UIColor colorWithRed:44.0/255.0 green:44.0/255.0 blue:46.0/255.0 alpha:1.0];
}
}];
} else {
switch (self.userInterfaceStyle) {
case UIUserInterfaceStyleLight:
return [UIColor whiteColor];
case UIUserInterfaceStyleDark:
default:
return [UIColor colorWithRed:44.0/255.0 green:44.0/255.0 blue:46.0/255.0 alpha:1.0];
}
[ThemeManager getUIStyle];
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 {
if (@available(iOS 13.0, *)) {
return [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
UIUserInterfaceStyle style = self.userInterfaceStyle;
if (style == UIUserInterfaceStyleUnspecified) {
// 跟随系统
style = traitCollection.userInterfaceStyle;
}
switch (style) {
case UIUserInterfaceStyleLight:
return [UIColor colorWithWhite:0.1 alpha:0.28];
case UIUserInterfaceStyleDark:
default:
return [UIColor colorWithWhite:0.28 alpha:1.0];
}
}];
} else {
[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;
}
}
}
+ (UIColor *)textColor {
if (@available(iOS 13.0, *)) {
return [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
UIUserInterfaceStyle style = self.userInterfaceStyle;
if (style == UIUserInterfaceStyleUnspecified) {
// 跟随系统
style = traitCollection.userInterfaceStyle;
}
switch (style) {
case UIUserInterfaceStyleLight:
return [UIColor blackColor];
case UIUserInterfaceStyleDark:
default:
return [UIColor whiteColor];
}
}];
} else {
[ThemeManager getUIStyle];
switch (self.userInterfaceStyle) {
case UIUserInterfaceStyleLight:
return [UIColor blackColor];
case UIUserInterfaceStyleDark:
default:
return [UIColor whiteColor];
}
case UIUserInterfaceStyleLight:
NSLog(@"themeLightTX");
return [UIColor blackColor];
break;
case UIUserInterfaceStyleDark:
default:
NSLog(@"themeDarkTX");
return [UIColor whiteColor];
break;
}
}
+2 -2
View File
@@ -12,8 +12,8 @@
@protocol HostCallback <NSObject>
- (void) hostClicked:(TemporaryHost*)host view:(UIView*)view;
- (void) hostLongClicked:(TemporaryHost*)host view:(UIView*)view;
- (void) addHostClicked;
- (void) hostCardLongPressed:(TemporaryHost*)host view:(UIView*)view;
- (void) addHostTapped;
@end
+3 -3
View File
@@ -216,7 +216,7 @@ static const int LABEL_DY = 20;
- (void) hostLongClicked:(UILongPressGestureRecognizer*)gesture {
if (gesture.state == UIGestureRecognizerStateBegan) {
[_callback hostLongClicked:_host view:self];
[_callback hostCardLongPressed:_host view:self];
}
}
@@ -228,7 +228,7 @@ static const int LABEL_DY = 20;
// effect of removing the touch highlight on this view.
[self cancelTrackingWithEvent:nil];
[_callback hostLongClicked:_host view:self];
[_callback hostCardLongPressed:_host view:self];
return nil;
}
#endif
@@ -238,7 +238,7 @@ static const int LABEL_DY = 20;
}
- (void) addClicked {
[_callback addHostClicked];
[_callback addHostTapped];
}
@end
@@ -27,6 +27,7 @@
/// 添加一个 item
- (void)addHost:(TemporaryHost *)host;
- (void)removeHost:(TemporaryHost *)host;
/// 移除最后一个 item(如果有)
- (void)removeLastItem;
@@ -11,7 +11,7 @@
#import "TemporaryHost.h"
#import "ThemeManager.h"
static const CGFloat cellOffsetY = 20;
@implementation HostCell {
UIViewController* parentVC;
@@ -43,7 +43,7 @@
- (void)assignDelegateForHostCard{
parentVC = [self viewController].parentViewController;
if(parentVC != nil){
if([parentVC conformsToProtocol:@protocol(HostCardButtonActionDelegate)]) self.cardView.delegate = (id<HostCardButtonActionDelegate>) parentVC;
if([parentVC conformsToProtocol:@protocol(HostCardActionDelegate)]) self.cardView.delegate = (id<HostCardActionDelegate>) parentVC;
}
}
@@ -59,7 +59,7 @@
[self.contentView addSubview:self.cardView];
[NSLayoutConstraint activateConstraints:@[
[self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.cardView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor],
[self.cardView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0],
]];
}
}
@@ -71,11 +71,13 @@
@property (nonatomic, strong) NSLayoutConstraint *collectionViewHeightConstraint;
@end
@implementation HostCollectionViewController
@implementation HostCollectionViewController{
UICollectionViewFlowLayout *layout;
}
- (instancetype)init {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 13); // 上、左、下、右的间距
layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(7, 0, 0, 0); // 上、左、下、右的间距
if (self = [super initWithCollectionViewLayout:layout]) {
_interItemMinimumSpacing = 10;
_minimumLineSpacing = 10;
@@ -97,6 +99,7 @@
// Fallback on earlier versions
}
self.collectionView.alwaysBounceVertical = NO;
self.collectionView.showsVerticalScrollIndicator = NO;
self.collectionView.backgroundColor = [ThemeManager appBackgroundColor];
}
@@ -121,14 +124,20 @@
[self.items addObject:host];
[self.items addObject:host];
[self.items addObject:host];
[self.collectionView reloadData];
// [self.view layoutIfNeeded];
}
NSLog(@"addhost log");
}
- (void)removeHost:(TemporaryHost *)host {
if([self.items containsObject:host]){
[self.items removeObject:host];
[self.collectionView reloadData];
}
}
- (void)removeLastItem {
if (self.items.count > 0) {
[self.items removeLastObject];
@@ -136,9 +145,27 @@
}
}
- (NSInteger)numberOfRowsInCollectionView{
NSInteger itemCount = [self.collectionView numberOfItemsInSection:0];
if (itemCount == 0) return 0;
NSMutableSet<NSNumber *> *rowYs = [NSMutableSet set];
for (NSInteger i = 0; i < itemCount; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *attr = [layout layoutAttributesForItemAtIndexPath:indexPath];
if (attr) {
CGFloat y = CGRectGetMinY(attr.frame);
[rowYs addObject:@(round(y))]; // round 防止浮点误差
}
}
return rowYs.count;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat contentHeight = self.collectionView.collectionViewLayout.collectionViewContentSize.height;
bool contentExceedsView = contentHeight > self.view.superview.bounds.size.height - self.view.frame.origin.y;
if(contentExceedsView){
@@ -146,7 +173,13 @@
[self.view.bottomAnchor constraintEqualToAnchor:self.view.superview.safeAreaLayoutGuide.bottomAnchor constant:0]
]];
}
else _collectionViewHeightConstraint.constant = contentHeight;
else{
_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);
}
#pragma mark - UICollectionView DataSource
@@ -21,13 +21,14 @@
#import "HostCollectionViewController.h"
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate, HostCardButtonActionDelegate>
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate, HostCardActionDelegate>
@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;
-(void)simulateSettingsButtonPress;
@@ -33,6 +33,7 @@
#import "CustomEdgeSlideGestureRecognizer.h"
#import "DataManager.h"
#import "ThemeManager.h"
#import "FixedTintImageView.h"
#import "Moonlight-Swift.h" // not used yet.
#if !TARGET_OS_TV
@@ -47,6 +48,9 @@
@implementation MainFrameViewController {
UILabel* waterMark;
UIBarButtonItem* addHostButton;
UIBarButtonItem* helpButton;
UILabel* hostViewTitleLabel;
//CGFloat recordedScreenWidth;
NSOperationQueue* _opQueue;
TemporaryHost* _selectedHost;
@@ -126,31 +130,44 @@ static NSMutableSet* hostList;
});
}
- (void)disableUpButton {
- (void)switchUIToHostView {
#if !TARGET_OS_TV
self.navigationItem.rightBarButtonItems = @[helpButton, addHostButton];
[self->_upButton setTitle:nil];
self.revealViewController.mainFrameIsInHostView = true; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view
[self setNeedsUpdateAllowedOrientation];
// [self setNeedsUpdateAllowedOrientation];
#endif
}
- (void)enableUpButton {
- (void)switchUIToAppView {
#if !TARGET_OS_TV
[self->_upButton setTitle: [LocalizationHelper localizedStringForKey: @"Select New Host"]];
self.navigationItem.rightBarButtonItems = @[_upButton];
self.revealViewController.mainFrameIsInHostView = false; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view
[self setNeedsUpdateAllowedOrientation];
// [self setNeedsUpdateAllowedOrientation];
#endif
}
- (void)updateTitle {
if (_selectedHost != nil) {
self.title = _selectedHost.name;
// self.title = _selectedHost.name;
}
else if ([hostList count] == 0) {
self.navigationController.navigationBar.titleTextAttributes = @{
NSFontAttributeName: [UIFont systemFontOfSize:20 weight:UIFontWeightMedium],
NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
};
self.title = [LocalizationHelper localizedStringForKey: @"Searching for PCs on your network..."] ;
}
else {
self.title = [LocalizationHelper localizedStringForKey: @"Select Host" ];
self.navigationController.navigationBar.titleTextAttributes = @{
NSFontAttributeName: [UIFont systemFontOfSize:24 weight:UIFontWeightSemibold],
NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色
};
self.title = [LocalizationHelper localizedStringForKey: @"Hosts" ];
//self.title = nil;
}
}
@@ -313,7 +330,7 @@ static NSMutableSet* hostList;
_sortedAppList = nil;
[self updateTitle];
[self disableUpButton];
[self switchUIToHostView];
[self.collectionView removeFromSuperview]; // necessary for new scroll host view reloading mechanism
[self reloadScrollHostView]; // host view must be reloaded here
@@ -345,12 +362,12 @@ static NSMutableSet* hostList;
[self.collectionView reloadData]; //for new scroll host view reloading mechanism
[self.view addSubview:self.collectionView]; //for new scroll host view reloading mechanism
[self attachWaterMark];
[self enableUpButton];
[self switchUIToAppView];
[self disableNavigation];
[self alreadyPaired];
}
- (void)leftButtonTappedForHost:(TemporaryHost *)host {
- (void)appButtonTappedForHost:(TemporaryHost *)host {
if (host.state != StateOnline) return;
_selectedHost = host;
if (host.state == StateOnline && host.pairState == PairStatePaired && host.appList.count > 0) {
@@ -359,8 +376,7 @@ static NSMutableSet* hostList;
}
- (void)rightButtonTappedForHost:(TemporaryHost *)host {
- (void)launchButtonTappedForHost:(TemporaryHost *)host {
_selectedHost = host;
if (host.state == StateOnline && host.pairState == PairStatePaired && host.appList.count > 0) {
[self enterAppView];
@@ -369,10 +385,11 @@ static NSMutableSet* hostList;
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
return;
}
NSLog(@"wake testtttttt: hostName: %@, states: %d, %d", host.name, host.state, host.pairState);
}
- (void)wakeupButtonTappedForHost:(TemporaryHost *)host{
_selectedHost = host;
NSLog(@"wake testtttttt: hostName: %@, states: %d, %d", host.name, host.state, host.pairState);
if (host.state == StateOffline && host.pairState == PairStatePaired) {
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert];
[wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
@@ -386,8 +403,6 @@ static NSMutableSet* hostList;
}
[[self activeViewController] presentViewController:wolAlert animated:YES completion:nil];
}
}
- (void)pairButtonTappedForHost:(TemporaryHost *)host{
@@ -459,19 +474,15 @@ static NSMutableSet* hostList;
}
});
}];
}
- (void) hostClicked:(TemporaryHost *)host view:(UIView *)view {
// Treat clicks on offline hosts to be long clicks
// This shows the context menu with wake, delete, etc. rather
// than just hanging for a while and failing as we would in this
// code path.
if (host.state != StateOnline && view != nil) {
[self hostLongClicked:host view:view];
[self hostCardLongPressed:host view:view];
return;
}
@@ -483,7 +494,7 @@ static NSMutableSet* hostList;
[self.collectionView reloadData]; //for new scroll host view reloading mechanism
[self.view addSubview:self.collectionView]; //for new scroll host view reloading mechanism
[self attachWaterMark];
[self enableUpButton];
[self switchUIToAppView];
[self disableNavigation];
#if TARGET_OS_TV
@@ -592,7 +603,14 @@ static NSMutableSet* hostList;
return topController;
}
- (void)hostLongClicked:(TemporaryHost *)host view:(UIView *)view {
- (void)restoreTintColorForAllSubViews{
for(UIView* view in self.view.subviews){ // iterates all on-screen widget views in StreamFrameView
view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
}
}
- (void)hostCardLongPressed:(TemporaryHost *)host view:(UIView *)view {
_selectedHost = host;
Log(LOG_D, @"Long clicked host: %@", host.name);
NSString* message;
@@ -619,8 +637,9 @@ static NSMutableSet* hostList;
}
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:message preferredStyle:UIAlertControllerStyleActionSheet];
if (host.state != StateOnline) {
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
/*[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert];
[wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) {
@@ -632,16 +651,17 @@ static NSMutableSet* hostList;
wolAlert.message = [LocalizationHelper localizedStringForKey:@"Successfully sent wake-up request. It may take a few moments for the PC to wake. If it never wakes up, ensure it's properly configured for Wake-on-LAN."];
}
[[self activeViewController] presentViewController:wolAlert animated:YES completion:nil];
}]];
}]];*/
}
else if (host.pairState == PairStatePaired) {
/*
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"View All Apps"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
self->_showHiddenApps = YES;
[self hostClicked:host view:view];
}]];
}]]; */
#if !TARGET_OS_TV
if (host.isNvidiaServerSoftware) {
if (false) {
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"NVIDIA GameStream End-of-Service"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/NVIDIA-GameStream-End-Of-Service-Announcement-FAQ"];
}]];
@@ -671,7 +691,10 @@ static NSMutableSet* hostList;
UIAlertController* netTestAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Network Test Complete"] message:message preferredStyle:UIAlertControllerStyleAlert];
[netTestAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
[[self activeViewController] presentViewController:netTestAlert animated:YES completion:nil];
[[self activeViewController] presentViewController:netTestAlert animated:YES completion:^{
NSLog(@"restore tint");
[self restoreTintColorForAllSubViews];
}];
}];
});
});
@@ -689,6 +712,7 @@ static NSMutableSet* hostList;
#endif
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Remove Host"] style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) { // host removed here
[self->_discMan removeHostFromDiscovery:host];
[self.hostCollectionVC removeHost:host];
DataManager* dataMan = [[DataManager alloc] init];
[dataMan removeHost:host];
@synchronized(hostList) {
@@ -706,8 +730,8 @@ static NSMutableSet* hostList;
[[self activeViewController] presentViewController:longClickAlert animated:YES completion:nil];
}
- (void) addHostClicked {
Log(LOG_D, @"Clicked add host");
- (void) addHostTapped {
Log(LOG_D, @"Tapped add host");
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Add Host Manually"] message:[LocalizationHelper localizedStringForKey:@"If Moonlight doesn't find your local gaming PC automatically, enter the IP address of your PC"] preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Cancel"] style:UIAlertActionStyleCancel handler:nil]];
[alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
@@ -1069,7 +1093,7 @@ 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.
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));
@@ -1092,6 +1116,14 @@ static NSMutableSet* hostList;
}
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position {
if (position == FrontViewPositionLeft) {
self.navigationItem.leftBarButtonItems = @[_settingsButton];
}
else {
self.navigationItem.leftBarButtonItems = @[];
}
SettingsViewController* settingsViewController = (SettingsViewController*)[revealController rearViewController];
settingsViewController.mainFrameViewController = self;
// enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable.
@@ -1204,7 +1236,7 @@ static NSMutableSet* hostList;
- (void)attachWaterMark {
// Create and configure the label
if(true){
if(false){
[self->waterMark removeFromSuperview];
self->waterMark = [[UILabel alloc] init];
self->waterMark.translatesAutoresizingMaskIntoConstraints = NO;
@@ -1244,7 +1276,7 @@ static NSMutableSet* hostList;
}
}
- (bool)isIphone{
- (bool)isIPhone{
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
}
@@ -1257,7 +1289,146 @@ static NSMutableSet* hostList;
// return isPortrait;
}
- (UIBarButtonItem *)createAddHostButton{
// 创建按钮
CGFloat buttonHeight = 30;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [ThemeManager appPrimaryColor]; // #0A85FF
button.layer.cornerRadius = buttonHeight/2;
button.clipsToBounds = YES;
// 设置图标(SF Symbol)
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:17 weight:UIImageSymbolWeightMedium];
UIImage *image = [UIImage systemImageNamed:@"plus.circle" withConfiguration:config];
[button setImage:image forState:UIControlStateNormal];
[button setTitle:@" Add Host" forState:UIControlStateNormal]; // 注意空格用于间隔
} else {
[button setTitle:@"Add Host" forState:UIControlStateNormal]; // 注意空格用于间隔
}
// [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
// 文字颜色设置为 tintColor 控制
button.tintColor = UIColor.whiteColor;
[button setTitleColor:button.tintColor forState:UIControlStateNormal];
// 设置按下时的 tintColor(变灰或淡)
UIColor *highlightColor = [ThemeManager textColorGray];
[button setTitleColor:highlightColor forState:UIControlStateHighlighted];
button.adjustsImageWhenHighlighted = YES; // 图标自动变淡
// 手动设定大小(如图中大约宽118高40)
button.frame = CGRectMake(0, 0, 130, buttonHeight);
// 添加点击事件
[button addTarget:self action:@selector(addHostTapped) forControlEvents:UIControlEventTouchUpInside];
// 创建 UIBarButtonItem
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return barItem;
}
- (UIBarButtonItem *)createHelpButton{
// 创建按钮
CGFloat buttonHeight = 30;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor clearColor]; // #0A85FF
// button.layer.cornerRadius = buttonHeight/2;
button.clipsToBounds = YES;
// 设置图标(SF Symbol)
if (@available(iOS 13.0, *)) {
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:buttonHeight*0.85 weight:UIImageSymbolWeightRegular];
UIImage *image = [UIImage systemImageNamed:@"questionmark.circle" withConfiguration:config];
[button setImage:image forState:UIControlStateNormal];
[button setTitle:@"" forState:UIControlStateNormal]; // 注意空格用于间隔
} else {
[button setTitle:@"Help" forState:UIControlStateNormal]; // 注意空格用于间隔
}
// [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:buttonHeight*0.6 weight:UIFontWeightMedium];
// 文字颜色设置为 tintColor 控制
button.tintColor = [ThemeManager appPrimaryColor];
[button setTitleColor:button.tintColor forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, buttonHeight, buttonHeight);
// 添加点击事件
// [button addTarget:self action:@selector(addDeviceTapped) forControlEvents:UIControlEventTouchUpInside];
// 创建 UIBarButtonItem
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return barItem;
}
- (CGFloat)getStandardNavBarHeight{
return [self isIPhone] ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad;
}
- (void)setupHostViewTitle{
self->hostViewTitleLabel = [[UILabel alloc] init];
hostViewTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
hostViewTitleLabel.numberOfLines = 1;
hostViewTitleLabel.font = [UIFont systemFontOfSize:30 weight:UIFontWeightSemibold];
hostViewTitleLabel.text = [LocalizationHelper localizedStringForKey:@"Hosts"];
// CGFloat labelHeight = 60;
hostViewTitleLabel.textColor = [ThemeManager textColor];
hostViewTitleLabel.textAlignment = NSTextAlignmentCenter;
// hostViewTitleLabel.backgroundColor = [UIColor clearColor];
hostViewTitleLabel.userInteractionEnabled = NO; // Enable user interaction for tap gesture
// Add tap gesture recognizer to handle hyperlink action
[self.view addSubview:hostViewTitleLabel];
// Set up constraints
[NSLayoutConstraint activateConstraints:@[
[hostViewTitleLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:0], // Aligns the horizontal center of label to the horizontal center of view
[hostViewTitleLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:25],
[hostViewTitleLabel.heightAnchor constraintEqualToConstant:30],
[hostViewTitleLabel.widthAnchor constraintEqualToConstant:100],
]];
}
- (void)setupNavBar{
self->addHostButton = [self createAddHostButton];
self->helpButton = [self createHelpButton];
//[self setupHostViewTitle];
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];
[_settingsButton setAction:@selector(revealToggle:)];
if (@available(iOS 13.0, *)) {
[_settingsButton setTitle:nil];
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:23 weight:UIImageSymbolWeightMedium ];
UIImage *image = [[UIImage systemImageNamed:@"sidebar.left" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[_settingsButton setImage:image];
_settingsButton.imageInsets = UIEdgeInsetsMake(10, 10, 0, 0);
} else {
[_settingsButton setTitle:[LocalizationHelper localizedStringForKey:@"Settings"]];
}
// Set the host name button action. When it's tapped, it'll show the host selection view.
[_upButton setTarget:self];
[_upButton setAction:@selector(showHostSelectionView)];
[self switchUIToHostView];
}
- (void)viewDidLoad{
[ThemeManager setUserInterfaceStyle:UIUserInterfaceStyleUnspecified];
[super viewDidLoad];
//[OrientationHelper updateOrientationToLandscape];
@@ -1267,14 +1438,7 @@ static NSMutableSet* hostList;
self.revealViewController.isStreaming = false; //init this flag for rvlVC
self.revealViewController.mainFrameIsInHostView = true;
// Set the side bar button action. When it's tapped, it'll show the sidebar.
[_settingsButton setTarget:self.revealViewController];
[_settingsButton setAction:@selector(revealToggle:)];
// Set the host name button action. When it's tapped, it'll show the host selection view.
[_upButton setTarget:self];
[_upButton setAction:@selector(showHostSelectionView)];
[self disableUpButton];
[self setupNavBar];
// Set the gesture
if(![self isIPhonePortrait]) [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; // to prevent buggy settings view in iphone portrait mode;
@@ -1369,7 +1533,7 @@ static NSMutableSet* hostList;
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self updateHosts];
}
@@ -1563,8 +1727,7 @@ static NSMutableSet* hostList;
{
[super viewDidAppear:NO];
// [self setupHostViewTitle];
// [self reloadScrollHostView]; //remove this for proper test
[self attachWaterMark];
@@ -1609,8 +1772,8 @@ static NSMutableSet* hostList;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[super viewWillAppear:NO];
/* this makes background color works*/
for (UIView *subview in self.view.subviews) {
[subview removeFromSuperview]; // 暂时移除所有子视图
@@ -1643,7 +1806,6 @@ static NSMutableSet* hostList;
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// when discovery stops, we must create a new instance because
// you cannot restart an NSOperation when it is finished
[_discMan stopDiscovery];
@@ -1985,7 +2147,7 @@ static NSMutableSet* hostList;
CGFloat hostCollectionViewPadding = 75;
self.hostCollectionVC.view.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.hostCollectionVC.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:50],
[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.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:0] //?
@@ -446,7 +446,7 @@ BOOL isCustomResolution(CGSize res) {
}
- (void)viewDidLoad {
// return;
BOOL isIPad = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
if(isIPad) [self layoutWidgetes]; // layout for ipad tmply
+6
View File
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
18341A042DEB662C0094E5F2 /* FixedTintImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18341A032DEB662C0094E5F2 /* FixedTintImageView.m */; };
189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */; };
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
841BAC922DE35D6B00DA639E /* ThemeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 841BAC912DE35D6B00DA639E /* ThemeManager.m */; };
@@ -128,6 +129,8 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
18341A022DEB65AB0094E5F2 /* FixedTintImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FixedTintImageView.h; sourceTree = "<group>"; };
18341A032DEB662C0094E5F2 /* FixedTintImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FixedTintImageView.m; sourceTree = "<group>"; };
189AD2962DE743B700E24B88 /* HostCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HostCollectionViewController.h; sourceTree = "<group>"; };
189AD2992DE7446000E24B88 /* HostCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HostCollectionViewController.m; sourceTree = "<group>"; };
566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.7.xcdatamodel"; sourceTree = "<group>"; };
@@ -500,6 +503,8 @@
FBD3495F1A004453002D2A60 /* Database */,
FB290CFA19B2C406004C83CF /* Supporting Files */,
FB290D0219B2C406004C83CF /* AppDelegate.h */,
18341A022DEB65AB0094E5F2 /* FixedTintImageView.h */,
18341A032DEB662C0094E5F2 /* FixedTintImageView.m */,
FB290D0319B2C406004C83CF /* AppDelegate.m */,
848F45682DDCD0D600581E36 /* HostCardView.h */,
848F45692DDCD12500581E36 /* HostCardView.m */,
@@ -928,6 +933,7 @@
FB9AFD3A1A7E05CE00872C98 /* ServerInfoResponse.m in Sources */,
84351B2B2C29AD6100A77989 /* LayoutOnScreenControlsViewController.m in Sources */,
84351B5C2C29ADBE00A77989 /* ProfileTableViewCell.m in Sources */,
18341A042DEB662C0094E5F2 /* FixedTintImageView.m in Sources */,
FB89463119F646E200339C8A /* StreamManager.m in Sources */,
84351B2D2C29AD6100A77989 /* ToolBarContainerView.m in Sources */,
988FCD41293B091B003050E2 /* KeyboardInputField.m in Sources */,