- fixes some UI memory leaks

- clear some obsolete codes
This commit is contained in:
TrueZhuanjia
2025-11-07 23:21:53 +08:00
parent 5750b99af3
commit 700552bd75
5 changed files with 56 additions and 122 deletions
-1
View File
@@ -425,7 +425,6 @@ static const float REFRESH_CYCLE = 2.0f;
[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;
@@ -56,11 +56,13 @@ static const CGFloat cellOffsetY = 20;
if (!self.cardView) {
self.cardView = [[HostCardView alloc] initWithHost:host andSizeFactor:[self getHostCardSizeFactor]];
[self assignDelegateForHostCard];
[self.contentView addSubview:self.cardView];
[NSLayoutConstraint activateConstraints:@[
[self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.cardView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0],
]];
if(!self.cardView.superview){
[self.contentView addSubview:self.cardView];
[NSLayoutConstraint activateConstraints:@[
[self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.cardView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0],
]];
}
}
}
@@ -69,6 +71,7 @@ static const CGFloat cellOffsetY = 20;
@interface HostCollectionViewController () <UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong, readwrite) NSMutableArray<TemporaryHost *> *items;
@property (nonatomic, strong) NSLayoutConstraint *collectionViewHeightConstraint;
@property (nonatomic, strong) NSLayoutConstraint *superViewBottomConstraint;
@end
@implementation HostCollectionViewController{
@@ -129,6 +132,8 @@ static const CGFloat cellOffsetY = 20;
- (void)addHost:(TemporaryHost *)host {
if(![self.items containsObject:host]){
[self.items addObject:host];
[self.items addObject:host];
[self.items addObject:host];
[self.collectionView reloadData];
}
@@ -173,9 +178,10 @@ static const CGFloat cellOffsetY = 20;
CGFloat contentHeight = self.collectionView.collectionViewLayout.collectionViewContentSize.height;
bool contentExceedsView = contentHeight > self.view.superview.bounds.size.height - self.view.frame.origin.y;
if(contentExceedsView){
[NSLayoutConstraint activateConstraints:@[
[self.view.bottomAnchor constraintEqualToAnchor:self.view.superview.safeAreaLayoutGuide.bottomAnchor constant:0]
]];
if(!_superViewBottomConstraint){
_superViewBottomConstraint = [self.view.bottomAnchor constraintEqualToAnchor:self.view.superview.safeAreaLayoutGuide.bottomAnchor constant:0];
_superViewBottomConstraint.active = YES;
}
}
else{
_collectionViewHeightConstraint.constant = contentHeight;
@@ -1134,20 +1134,6 @@ 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.
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.
});
}
// currently obselete:
- (void) setNeedsUpdateAllowedOrientation{
if (@available(iOS 16.0, *)) {
@@ -1283,7 +1269,7 @@ static NSMutableSet* hostList;
// Create and configure the label
if (@available(iOS 13.0, *)) return;
else {
[self->waterMark removeFromSuperview];
[self->waterMark removeFromSuperview]; // removed before activate contraint
self->waterMark = [[UILabel alloc] init];
self->waterMark.translatesAutoresizingMaskIntoConstraints = NO;
self->waterMark.numberOfLines = 1;
@@ -1426,31 +1412,6 @@ static NSMutableSet* hostList;
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)applyNavBarAppearance{
if (@available(iOS 13.0, *)) {
self.navigationController.navigationBar.standardAppearance.backgroundColor = [UIColor clearColor]; // old ios depend on this, do not remove
@@ -1572,11 +1533,6 @@ static NSMutableSet* hostList;
TemporarySettings* tempSettings = [dataMan getSettings];
[ThemeManager setUserInterfaceStyle:tempSettings.appTheme.intValue];
[[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
@@ -1847,10 +1803,6 @@ static NSMutableSet* hostList;
[self attachWaterMark];
#if !TARGET_OS_TV
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleOrientationChange) // //force expand settings view to update resolution table, and all setting includes current fullscreen resolution will be updated.
name:UIDeviceOrientationDidChangeNotification
object:nil];
[[self revealViewController] setPrimaryViewController:self];
self.revealViewController.isStreaming = false; // tell the revealViewController streaming is finished
@@ -2036,20 +1988,6 @@ static NSMutableSet* hostList;
[_discMan resetDiscoveryState];
}
// This function forces immediate decoding of the UIImage, rather
// than the default lazy decoding that results in janky scrolling.
-(void)deviceOrientationDidChange{
if(self.revealViewController.isStreaming || 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;
@@ -2339,19 +2277,18 @@ static NSMutableSet* hostList;
self.hostCollectionVC.minimumLineSpacing = 25;
// 添加为子控制器
[self addChildViewController:self.hostCollectionVC];
[self.view addSubview:self.hostCollectionVC.view];
// 设置其布局(Auto Layout 示例)
// CGFloat hostCollectionViewPadding = 75;
CGFloat leftPadding = [self isIPhone] ? 30 : 0;
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:leftPadding],
[self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:0],
// [self.hostCollectionVC.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:0] //?
]];
if(self.hostCollectionVC.view.superview == nil){
[self.view addSubview:self.hostCollectionVC.view];
CGFloat leftPadding = [self isIPhone] ? 30 : 0;
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:leftPadding],
[self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:0],
]];
}
// 通知子控制器已添加完成
[self.hostCollectionVC didMoveToParentViewController:self];
@@ -157,6 +157,13 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
[self insertSubview:_rearNavView belowSubview:_frontView];
[self insertSubview:_safeAreaPadding belowSubview:_frontView];
[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
]];
CGFloat navBarHeight = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad;
@@ -263,14 +270,7 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1
_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
}
@@ -984,7 +984,7 @@ const int FrontViewPositionNone = 0xff;
[_dockedNavBar setItems:@[_navItem]];
_dockedNavBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor]};
[_dockedNavBar removeFromSuperview];
[_dockedNavBar removeFromSuperview]; // removed before activate contraints
[_contentView.rearNavView addSubview:_dockedNavBar];
// 设置导航栏约束
@@ -995,7 +995,7 @@ const int FrontViewPositionNone = 0xff;
[_dockedNavBar.widthAnchor constraintEqualToConstant:_rearViewRevealWidth],
]];
[self layoutSettingsView];
// NSLog(@"leak test %f %lu", CACurrentMediaTime(), _contentView.rearNavView.constraints.count);
}
@@ -31,7 +31,8 @@
NSLayoutConstraint *parentStackLeadingConstraint;
NSLayoutConstraint *parentStackWidthConstraint;
NSLayoutConstraint *parentStackCenterXConstraint;
NSInteger _bitrate;
NSInteger _lastSelectedResolutionIndex;
bool settingsViewJustLoaded;
@@ -503,28 +504,19 @@ BOOL isCustomResolution(int resolutionSelected) {
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;
_parentStack.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:_parentStack];
[NSLayoutConstraint activateConstraints:@[
[_parentStack.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor constant: currentSettingsMenuMode == AllSettings ? [self getStandardNavBarHeight] : [self getStandardNavBarHeight]+10],
[_parentStack.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor constant:-20],
]];
if(!_parentStack.superview){
[self.scrollView addSubview:_parentStack];
[NSLayoutConstraint activateConstraints:@[
[_parentStack.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor constant: currentSettingsMenuMode == AllSettings ? [self getStandardNavBarHeight] : [self getStandardNavBarHeight]+10],
[_parentStack.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor constant:-20],
]];
}
[self updateParentStackHorizontalConstraints];
}
@@ -534,10 +526,10 @@ BOOL isCustomResolution(int resolutionSelected) {
- (void)updateParentStackHorizontalConstraints{
if(![self isIPhone]){
[NSLayoutConstraint activateConstraints:@[
[_parentStack.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant: 0], //mark: settingMenuLayout
[_parentStack.widthAnchor constraintEqualToAnchor:self.view.widthAnchor constant:-20] // section width adjusted here
]];
if(parentStackCenterXConstraint && parentStackWidthConstraint) [NSLayoutConstraint deactivateConstraints:@[parentStackCenterXConstraint, parentStackWidthConstraint]];
parentStackCenterXConstraint = [_parentStack.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant: 0]; //mark: settingMenuLayout
parentStackWidthConstraint = [_parentStack.widthAnchor constraintEqualToAnchor:self.view.widthAnchor constant:-20]; // section width adjusted here
[NSLayoutConstraint activateConstraints:@[parentStackCenterXConstraint, parentStackWidthConstraint]];
return;
}
@@ -552,7 +544,8 @@ BOOL isCustomResolution(int resolutionSelected) {
currentOrientation = activeScene.interfaceOrientation;
}
else currentOrientation = keyWindow.windowScene.interfaceOrientation;
if(parentStackLeadingConstraint && parentStackWidthConstraint) [NSLayoutConstraint deactivateConstraints:@[parentStackLeadingConstraint, parentStackWidthConstraint]];
switch (currentOrientation) {
case UIInterfaceOrientationLandscapeRight:
parentStackLeadingConstraint = [_parentStack.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:0];
@@ -567,8 +560,7 @@ BOOL isCustomResolution(int resolutionSelected) {
} else {
// Fallback on earlier versions
}
double delayInSeconds = 0.05;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^{
@@ -677,10 +669,10 @@ BOOL isCustomResolution(int resolutionSelected) {
}
}
- (void)addSetting:(UIStackView *)stack ofId:(NSString* )identifier withInfoTag:(BOOL)attched withDynamicLabel:(BOOL)added to:(MenuSectionView* )menuSection{
- (void)addSetting:(UIStackView *)stack ofId:(NSString* )identifier withInfoTag:(BOOL)attached withDynamicLabel:(BOOL)added to:(MenuSectionView* )menuSection{
stack.accessibilityIdentifier = identifier;
[_settingStackDict setObject:stack forKey:identifier];
if(attched) [self attachInfoTagForStack:stack];
if(attached) [self attachInfoTagForStack:stack];
if(added) [self addDynamicLabelForStack:stack];
[menuSection addSubStackView:stack];
}