- notification lifecycle fixes - replace some notifications with delegates

- fix osw profile switch issue
This commit is contained in:
TrueZhuanjia
2025-06-22 21:25:29 +08:00
parent cd6e08956c
commit 6bc142a07b
12 changed files with 89 additions and 96 deletions
@@ -34,7 +34,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) updateGuidelinesForOnScreenWidget:(OnScreenWidgetView* )widget;
- (void)updateGuidelinesForOnScreenWidget:(OnScreenWidgetView* )widget;
@end
NS_ASSUME_NONNULL_END
@@ -32,11 +32,6 @@
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleMovingOnScreenWidgetNotification:)
name:@"OnScreenWidgetMovedByTouch"
object:nil];
_view = view;
_view.multipleTouchEnabled = false;
@@ -121,12 +116,7 @@
[self._view addSubview: verticalGuideline];
}
- (void) handleMovingOnScreenWidgetNotification: (NSNotification *)notification{
OnScreenWidgetView* widget = notification.object;
[self updateGuidelinesForOnScreenWidget:widget];
}
- (void) updateGuidelinesForOnScreenWidget: (OnScreenWidgetView* )widget{
- (void)updateGuidelinesForOnScreenWidget:(OnScreenWidgetView* )widget{
/* have guidelines follow wherever the user is touching on the screen */
horizontalGuideline.hidden = verticalGuideline.hidden = NO;
horizontalGuideline.center = verticalGuideline.center = CGPointMake(CGRectGetMidX(widget.frame), CGRectGetMidY(widget.frame));
@@ -349,5 +339,4 @@
}
@end
+7 -1
View File
@@ -19,6 +19,12 @@ import UIKit
}
}
@objc protocol OnScreenWidgetGuidelineUpdateDelegate: AnyObject {
func updateGuidelinesForOnScreenWidget(_ sender: Any)
}
@objc public weak var guidelineDelegate: OnScreenWidgetGuidelineUpdateDelegate?
enum WidgetTypeEnum: UInt8 {
case uninitialized = 0
case button = 1
@@ -1079,7 +1085,7 @@ import UIKit
// center = currentLocation;
//NSLog("x coord: %f, y coord: %f", self.frame.origin.x, self.frame.origin.y)
if OnScreenWidgetView.editMode {
NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetMovedByTouch"), object:self) // inform the layoutOnScreenControl to update guideLines for this widget view
guidelineDelegate?.updateGuidelinesForOnScreenWidget(self)
}
}
+10 -6
View File
@@ -18,12 +18,12 @@
@protocol UserInteractionDelegate <NSObject>
- (void) userInteractionBegan;
- (void) userInteractionEnded;
- (void) streamExitRequested;
- (void) toggleStatsOverlay;
- (void) localMousePointerMode;
- (void) toggleMouseVisible;
- (void)userInteractionBegan;
- (void)userInteractionEnded;
- (void)streamExitRequested;
- (void)toggleStatsOverlay;
- (void)localMousePointerMode;
- (void)toggleMouseVisible;
@end
@@ -57,6 +57,10 @@
- (OnScreenControlsLevel) getCurrentOscState;
- (void)keyboardWillShow:(NSNotification *)notification;
- (void)keyboardWillHide;
#if !TARGET_OS_TV
- (void) updateCursorLocation:(CGPoint)location isMouse:(BOOL)isMouse;
#endif
+3 -12
View File
@@ -104,15 +104,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
keyboardToggleRecognizer.tapDownTimeThreshold = 0.2; // tap down time threshold in seconds.
keyboardToggleRecognizer.delaysTouchesBegan = NO;
keyboardToggleRecognizer.delaysTouchesEnded = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
NSLog(@"setup streamView %f", CACurrentMediaTime());
// if(settings.touchMode.intValue == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode
// else [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes
@@ -233,11 +225,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
self.frame = liftedStreamFrame;
isInputingText = true;
}
// NSLog(@"keyboard will show");
NSLog(@"keyboard will show %f", CACurrentMediaTime());
}
// this method also deals with recovering streamview when local keyboard is turned off
- (void)keyboardWillHide:(NSNotification *)notification{
- (void)keyboardWillHide{
if(isInputingText){
CGRect liftedStreamFrame = self.frame;
@@ -246,7 +238,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
self.frame = liftedStreamFrame;
isInputingText = false;
}
// NSLog(@"keyboard will hide");
}
+1 -1
View File
@@ -76,7 +76,7 @@
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<false/>
<true/>
<key>UIStatusBarHidden</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
+3 -2
View File
@@ -79,6 +79,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
- (id)initWithView:(StreamView*)view callbacks:(id<ConnectionCallbacks>)callbacks streamAspectRatio:(float)aspectRatio useFramePacing:(BOOL)useFramePacing
{
NSLog(@"initializing video decoder %f", CACurrentMediaTime());
self = [super init];
_view = view;
@@ -145,8 +146,8 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
}
}
- (void)stop
{
- (void)stop{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_displayLink invalidate];
}
@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
This view controller provides the user interface which allows the user to position on screen controller buttons anywhere they'd like on the screen. It also provides the user with the abilities to undo a change, save the on screen controller layout for later retrieval, and load previously saved controller layouts
*/
@interface LayoutOnScreenControlsViewController : UIViewController
@interface LayoutOnScreenControlsViewController : UIViewController <OnScreenWidgetGuidelineUpdateDelegate>
- (void)profileRefresh;
- (void)reloadOnScreenWidgetViews;
- (void)presentProfilesTableView;
@@ -79,6 +79,7 @@
}
- (void) reloadOnScreenWidgetViews {
NSLog(@"reloadOnScreenWidgets %f", CACurrentMediaTime());
OnScreenWidgetView.editMode = true;
[self->selectedWidgetView.stickBallLayer removeFromSuperlayer];
[self->selectedWidgetView.crossMarkLayer removeFromSuperlayer];
@@ -101,6 +102,7 @@
OnScreenButtonState* buttonState = [profilesManager unarchiveButtonStateEncoded:buttonStateEncoded];
if(buttonState.buttonType == CustomOnScreenWidget){
OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithCmdString:buttonState.name buttonLabel:buttonState.alias shape:buttonState.widgetShape]; //reconstruct widgetView
widgetView.guidelineDelegate = (id<OnScreenWidgetGuidelineUpdateDelegate>)self;
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.widthFactor = buttonState.widthFactor;
widgetView.heightFactor = buttonState.heightFactor;
@@ -166,38 +168,7 @@
if (![profilesManager profileName:DEFAULT_TEMPLATE_NAME alreadyExistIn:allProfiles]){
[profilesManager importDefaultTemplates];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(legacyOscLayerTapped:)
name:@"LegacyOscCALayerSelectedNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleProfileTablViewDismiss)
name:@"OscLayoutTableViewCloseNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadOnScreenWidgetViews)
name:@"OscLayoutProfileSelctedInTableView" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(widgetViewTapped:)
name:@"OnScreenWidgetViewSelected"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleMovingOnScreenWidgetNotification:)
name:@"OnScreenWidgetMovedByTouch"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OSCLayoutChanged) name:@"OSCLayoutChanged" object:nil]; // used to notifiy this view controller that the user made a change to the OSC layout so that the VC can either fade in or out its 'Undo button' which will signify to the user whether there are any OSC layout changes to undo
/* This will animate the toolbar with a subtle up and down motion intended to telegraph to the user that they can hide the toolbar if they wish*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -230,15 +201,42 @@
vibrationGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
}
- (void)viewDidDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void) viewDidAppear:(BOOL)animated {
- (void)viewDidAppear:(BOOL)animated {
OnScreenWidgetView.editMode = true;
selectedWidgetView = nil;
widgetPanelStoredCenter = self.widgetPanelStack.center;
[super viewDidAppear:animated];
}
- (void) viewWillAppear:(BOOL)animated{
- (void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(legacyOscLayerTapped:)
name:@"LegacyOscCALayerSelectedNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleProfileTablViewDismiss)
name:@"OscLayoutTableViewCloseNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadOnScreenWidgetViews)
name:@"OscLayoutProfileSelctedInTableView" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(widgetViewTapped:)
name:@"OnScreenWidgetViewSelected"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OSCLayoutChanged) name:@"OSCLayoutChanged" object:nil]; // used to notifiy this view controller that the user made a change to the OSC layout so that the VC can either fade in or out its 'Undo button' which will signify to the user whether there are any OSC layout changes to undo
OnScreenWidgetView.editMode = true;
[self handleMissingToolBarIcon:toolbarRootView];
[self profileRefresh];
@@ -830,8 +828,7 @@
- (void)setupWidgetPanel{
//[self handleMissingToolBarIcon];
self.widgetPanelStack.hidden = NO;
self.widgetPanelStack.hidden = _quickSwitchEnabled;
self.loadConfigTipLabel.hidden = NO;
self.widgetPanelStack.layoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
@@ -1020,14 +1017,14 @@
#pragma mark - Touch
- (void) handleMovingOnScreenWidgetNotification: (NSNotification *)notification{
OnScreenWidgetView* widget = notification.object;
- (void)updateGuidelinesForOnScreenWidget:(id)sender{
OnScreenWidgetView* widget = (OnScreenWidgetView* )sender;
[self.layoutOSC updateGuidelinesForOnScreenWidget:widget];
[self.view bringSubviewToFront:widget];
trashCanButton.tintColor = [self layerOverlapWithTrashcanButton:widget.layer] ? [UIColor redColor] : trashCanStoryBoardColor;
self.undoButton.alpha = 1.0;
}
- (BOOL) widgetPanelTouched:(UITouch *)touch{
CGPoint touchPoint = [touch locationInView:_widgetPanelStack];
UIView *touchedView = [_widgetPanelStack hitTest:touchPoint withEvent:nil];
@@ -43,8 +43,8 @@ const double NAV_BAR_HEIGHT = 50;
}
- (void) viewDidDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutTableViewCloseNotification" object:self]; // notify other view that oscLayoutManager is closing
[super viewDidDisappear:animated];
}
@@ -305,18 +305,6 @@ BOOL isCustomResolution(CGSize res) {
}
- (void)deviceOrientationDidChange{
double delayInSeconds = 1.0;
// 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 updateResolutionTable];
// since we have viewWillTransitionToSize being called back both when orientation changed & app window size changed, resoltion update is dprecated here
});
}
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:NO];
[[NSNotificationCenter defaultCenter] postNotificationName:@"SettingsViewClosedNotification" object:self]; // notify other view that settings view just closed
@@ -1174,10 +1162,6 @@ BOOL isCustomResolution(CGSize res) {
[self.view addGestureRecognizer:slideToCloseSettingsViewRecognizer];
justEnteredSettingsViewDoNotOpenOscLayoutTool = true;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChange) // handle orientation change since i made portrait mode available
name:UIDeviceOrientationDidChangeNotification
object:nil];
// Always run settings in dark mode because we want the light fonts
if (@available(iOS 13.0, tvOS 13.0, *)) {
@@ -1411,7 +1395,7 @@ BOOL isCustomResolution(CGSize res) {
// init CustomOSC stuff
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
self.layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
// self.layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
if (isIPhone) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
@@ -107,7 +107,7 @@
[self.view addGestureRecognizer:_oscLayoutTapRecoginizer]; //
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
_layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
// _layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
if (isIPhone) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
@@ -267,6 +267,17 @@
selector:@selector(expandSettingsView) // //force expand settings view to update resolution table, and all setting includes current fullscreen resolution will be updated.
name:@"SettingsOverlayButtonPressedNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
#endif
}
@@ -433,12 +444,12 @@
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
[[NSNotificationCenter defaultCenter] addObserver:self
selector: @selector(applicationDidBecomeActive:)
name: UIApplicationDidBecomeActiveNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
[[NSNotificationCenter defaultCenter] addObserver:self
selector: @selector(applicationDidEnterBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
@@ -468,6 +479,15 @@
[self.view addSubview:_tipLabel];
}
- (void)keyboardWillShow:(NSNotification *)notification{
[_streamView keyboardWillShow:notification];
}
- (void)keyboardWillHide{
[_streamView keyboardWillHide];
}
- (void)openWidgetLayoutTool{
[self->_streamView disableOnScreenControls];
[self->_streamView clearOnScreenKeyboardButtons]; // clear all onScreenKeyboardButtons before entering edit mode