From d8a6b66b864de957253596638d82bfa4628639dc Mon Sep 17 00:00:00 2001 From: "ZhiQuan.Yang" Date: Wed, 7 May 2014 17:44:09 +0800 Subject: [PATCH 1/4] a little logic issue create rippleView while rootViewController's view not contains it. --- Classes/COSTouchVisualizerWindow.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Classes/COSTouchVisualizerWindow.m b/Classes/COSTouchVisualizerWindow.m index 3efc4b3..1ad2ea2 100644 --- a/Classes/COSTouchVisualizerWindow.m +++ b/Classes/COSTouchVisualizerWindow.m @@ -209,9 +209,10 @@ { // Generate ripples COSTouchSpotView *rippleView = (COSTouchSpotView *)[self.overlayWindow.rootViewController.view viewWithTag:touch.hash]; - - rippleView = [[COSTouchSpotView alloc] initWithImage:self.rippleImage]; - [self.overlayWindow.rootViewController.view addSubview:rippleView]; + if(!rippleView){ + rippleView = [[COSTouchSpotView alloc] initWithImage:self.rippleImage]; + [self.overlayWindow.rootViewController.view addSubview:rippleView]; + } rippleView.alpha = self.rippleAlpha; rippleView.center = [touch locationInView:self.overlayWindow.rootViewController.view]; @@ -401,4 +402,4 @@ @implementation COSTouchSpotView -@end \ No newline at end of file +@end From a4fa33f31e37813b9496e30628136adec7f32b58 Mon Sep 17 00:00:00 2001 From: "ZhiQuan.Yang" Date: Wed, 7 May 2014 17:52:46 +0800 Subject: [PATCH 2/4] Update COSTouchVisualizerWindow.m --- Classes/COSTouchVisualizerWindow.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Classes/COSTouchVisualizerWindow.m b/Classes/COSTouchVisualizerWindow.m index 1ad2ea2..cb3de13 100644 --- a/Classes/COSTouchVisualizerWindow.m +++ b/Classes/COSTouchVisualizerWindow.m @@ -208,12 +208,9 @@ case UITouchPhaseMoved: { // Generate ripples - COSTouchSpotView *rippleView = (COSTouchSpotView *)[self.overlayWindow.rootViewController.view viewWithTag:touch.hash]; - if(!rippleView){ - rippleView = [[COSTouchSpotView alloc] initWithImage:self.rippleImage]; + COSTouchSpotView *rippleView = [[COSTouchSpotView alloc] initWithImage:self.rippleImage]; [self.overlayWindow.rootViewController.view addSubview:rippleView]; - } - + rippleView.alpha = self.rippleAlpha; rippleView.center = [touch locationInView:self.overlayWindow.rootViewController.view]; From 381f360a9e1a97e9b3cb47edde7d63eb883a5998 Mon Sep 17 00:00:00 2001 From: Rene Lindhorst Date: Mon, 16 Jun 2014 13:21:54 +0200 Subject: [PATCH 3/4] added a flag to disable the morphing of a stationary view spot --- Classes/COSTouchVisualizerWindow.h | 2 ++ Classes/COSTouchVisualizerWindow.m | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) mode change 100644 => 100755 Classes/COSTouchVisualizerWindow.h mode change 100644 => 100755 Classes/COSTouchVisualizerWindow.m diff --git a/Classes/COSTouchVisualizerWindow.h b/Classes/COSTouchVisualizerWindow.h old mode 100644 new mode 100755 index e3aeeea..3a3c83f --- a/Classes/COSTouchVisualizerWindow.h +++ b/Classes/COSTouchVisualizerWindow.h @@ -23,4 +23,6 @@ @property (nonatomic, strong) UIColor *rippleStrokeColor; @property (nonatomic, strong) UIColor *rippleFillColor; +@property (nonatomic) BOOL stationaryMorphEnabled; // default: YES + @end diff --git a/Classes/COSTouchVisualizerWindow.m b/Classes/COSTouchVisualizerWindow.m old mode 100644 new mode 100755 index cb3de13..bb4de62 --- a/Classes/COSTouchVisualizerWindow.m +++ b/Classes/COSTouchVisualizerWindow.m @@ -93,7 +93,9 @@ self.rippleAlpha = 0.2; self.rippleFadeDuration = 0.2; - + + self.stationaryMorphEnabled = YES; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenConnect:) name:UIScreenDidConnectNotification @@ -239,7 +241,9 @@ touchView = [[COSTouchSpotView alloc] initWithImage:self.touchImage]; [self.overlayWindow.rootViewController.view addSubview:touchView]; - self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(performMorph:) userInfo:touchView repeats:YES]; + if (self.stationaryMorphEnabled) { + self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(performMorph:) userInfo:touchView repeats:YES]; + } } if (![touchView isFadingOut]) { From 33c3d35f046852eb1bb8e41a09a2932836780f39 Mon Sep 17 00:00:00 2001 From: Rene Lindhorst Date: Tue, 17 Jun 2014 10:08:51 +0200 Subject: [PATCH 4/4] FIXED rotation issue by not assigning a RootViewController to the OverlayWindow + avoid "Application windows are expected to have a root view controller at the end of application launch" waring by moving window creation into getter --- Classes/COSTouchVisualizerWindow.m | 36 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/Classes/COSTouchVisualizerWindow.m b/Classes/COSTouchVisualizerWindow.m index bb4de62..75a8434 100755 --- a/Classes/COSTouchVisualizerWindow.m +++ b/Classes/COSTouchVisualizerWindow.m @@ -81,13 +81,6 @@ self.rippleStrokeColor = [UIColor whiteColor]; self.rippleFillColor = [UIColor blueColor]; - self.overlayWindow = [[UIWindow alloc] initWithFrame:self.frame]; - self.overlayWindow.rootViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; - self.overlayWindow.userInteractionEnabled = NO; - self.overlayWindow.windowLevel = UIWindowLevelStatusBar; - self.overlayWindow.backgroundColor = [UIColor clearColor]; - self.overlayWindow.hidden = NO; - self.touchAlpha = 0.5; self.fadeDuration = 0.3; @@ -114,6 +107,7 @@ [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenDidConnectNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenDidDisconnectNotification object:nil]; } + #pragma mark - - (UIImage *)touchImage { @@ -211,10 +205,10 @@ { // Generate ripples COSTouchSpotView *rippleView = [[COSTouchSpotView alloc] initWithImage:self.rippleImage]; - [self.overlayWindow.rootViewController.view addSubview:rippleView]; + [self.overlayWindow addSubview:rippleView]; rippleView.alpha = self.rippleAlpha; - rippleView.center = [touch locationInView:self.overlayWindow.rootViewController.view]; + rippleView.center = [touch locationInView:self.overlayWindow]; [UIView animateWithDuration:self.rippleFadeDuration delay:0.0 @@ -229,7 +223,7 @@ } case UITouchPhaseStationary: { - COSTouchSpotView *touchView = (COSTouchSpotView *)[self.overlayWindow.rootViewController.view viewWithTag:touch.hash]; + COSTouchSpotView *touchView = (COSTouchSpotView *)[self.overlayWindow viewWithTag:touch.hash]; if (touch.phase != UITouchPhaseStationary && touchView != nil && [touchView isFadingOut]) { [self.timer invalidate]; @@ -239,7 +233,7 @@ if (touchView == nil && touch.phase != UITouchPhaseStationary) { touchView = [[COSTouchSpotView alloc] initWithImage:self.touchImage]; - [self.overlayWindow.rootViewController.view addSubview:touchView]; + [self.overlayWindow addSubview:touchView]; if (self.stationaryMorphEnabled) { self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(performMorph:) userInfo:touchView repeats:YES]; @@ -248,7 +242,7 @@ if (![touchView isFadingOut]) { touchView.alpha = self.touchAlpha; - touchView.center = [touch locationInView:self.overlayWindow.rootViewController.view]; + touchView.center = [touch locationInView:self.overlayWindow]; touchView.tag = touch.hash; touchView.timestamp = touch.timestamp; touchView.shouldAutomaticallyRemoveAfterTimeout = [self shouldAutomaticallyRemoveFingerTipForTouch:touch]; @@ -274,6 +268,18 @@ #pragma mark - #pragma mark Private +- (UIWindow *)overlayWindow { + if (!_overlayWindow) { + _overlayWindow = [[UIWindow alloc] initWithFrame:self.frame]; + _overlayWindow.userInteractionEnabled = NO; + _overlayWindow.windowLevel = UIWindowLevelStatusBar; + _overlayWindow.backgroundColor = [UIColor clearColor]; + _overlayWindow.hidden = NO; + } + + return _overlayWindow; +} + - (void)scheduleFingerTipRemoval { if (self.fingerTipRemovalScheduled) return; self.fingerTipRemovalScheduled = YES; @@ -291,19 +297,19 @@ NSTimeInterval now = [[NSProcessInfo processInfo] systemUptime]; const CGFloat REMOVAL_DELAY = 0.2; - for (COSTouchSpotView *touchView in [self.overlayWindow.rootViewController.view subviews]) { + for (COSTouchSpotView *touchView in [self.overlayWindow subviews]) { if (![touchView isKindOfClass:[COSTouchSpotView class]]) continue; if (touchView.shouldAutomaticallyRemoveAfterTimeout && now > touchView.timestamp + REMOVAL_DELAY) [self removeFingerTipWithHash:touchView.tag animated:YES]; } - if ([[self.overlayWindow.rootViewController.view subviews] count]) + if ([[self.overlayWindow subviews] count]) [self scheduleFingerTipRemoval]; } - (void)removeFingerTipWithHash:(NSUInteger)hash animated:(BOOL)animated { - COSTouchSpotView *touchView = (COSTouchSpotView *)[self.overlayWindow.rootViewController.view viewWithTag:hash]; + COSTouchSpotView *touchView = (COSTouchSpotView *)[self.overlayWindow viewWithTag:hash]; if (touchView == nil) return;