diff options
author | Joel Fischer <joeljfischer@gmail.com> | 2019-04-04 15:17:54 -0400 |
---|---|---|
committer | Joel Fischer <joeljfischer@gmail.com> | 2019-04-04 15:17:54 -0400 |
commit | bb40d29d305f82ae25b4dc3013bdf74249bbb51c (patch) | |
tree | 5477a349e00f9e2f9e96f8b2ee456146ed6b9fa0 | |
parent | 9e07277ee606f398743f887ec1a5300a30f1b96a (diff) | |
parent | 6a7ee983bf1e9f97561b306780ad0f12294a55ef (diff) | |
download | sdl_ios-bb40d29d305f82ae25b4dc3013bdf74249bbb51c.tar.gz |
Merge branch 'develop' into feature/issue_1212_update_system_capability_manager_auto_caching
-rw-r--r-- | SmartDeviceLink/SDLFocusableItemLocator.m | 8 | ||||
-rw-r--r-- | SmartDeviceLink/SDLLifecycleManager.h | 4 | ||||
-rw-r--r-- | SmartDeviceLink/SDLTouchManager.m | 52 | ||||
-rw-r--r-- | SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m | 148 |
4 files changed, 120 insertions, 92 deletions
diff --git a/SmartDeviceLink/SDLFocusableItemLocator.m b/SmartDeviceLink/SDLFocusableItemLocator.m index 1969512e5..e3fb4d451 100644 --- a/SmartDeviceLink/SDLFocusableItemLocator.m +++ b/SmartDeviceLink/SDLFocusableItemLocator.m @@ -105,7 +105,7 @@ NS_ASSUME_NONNULL_BEGIN } NSMutableArray<SDLHapticRect *> *hapticRects = [[NSMutableArray alloc] init]; - + for (UIView *view in self.focusableViews) { CGPoint originOnScreen = [self.viewController.view convertPoint:view.frame.origin toView:nil]; CGRect convertedRect = {originOnScreen, view.bounds.size}; @@ -115,7 +115,7 @@ NS_ASSUME_NONNULL_BEGIN SDLHapticRect *hapticRect = [[SDLHapticRect alloc] initWithId:(UInt32)rectId rect:rect]; [hapticRects addObject:hapticRect]; } - + SDLSendHapticData* hapticRPC = [[SDLSendHapticData alloc] initWithHapticRectData:hapticRects]; [self.connectionManager sendConnectionManagerRequest:hapticRPC withResponseHandler:nil]; } @@ -123,7 +123,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark SDLFocusableItemHitTester functions - (nullable UIView *)viewForPoint:(CGPoint)point { UIView *selectedView = nil; - + for (UIView *view in self.focusableViews) { //Convert the absolute location to local location and check if that falls within view boundary CGPoint localPoint = [view convertPoint:point fromView:self.viewController.view]; @@ -137,7 +137,7 @@ NS_ASSUME_NONNULL_BEGIN } } } - + return selectedView; } diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h index b3a58e35c..dfb8c5140 100644 --- a/SmartDeviceLink/SDLLifecycleManager.h +++ b/SmartDeviceLink/SDLLifecycleManager.h @@ -106,12 +106,16 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); /** * Start the manager, which will tell it to start looking for a connection. Once one does, it will automatically run the setup process and call the readyBlock when done. * + * @warning If you call this method from SDLManager's `startWithReadyHandler` be sure to wrap the `stop` call inside a dispatch_async and send it to the main queue or a global queue, otherwise calling `stop` may cause a deadlock. + * * @param readyHandler The block called when the manager is ready to be used or an error occurs while attempting to become ready. */ - (void)startWithReadyHandler:(SDLManagerReadyBlock)readyHandler; /** * Stop the manager, it will disconnect if needed and no longer look for a connection. You probably don't need to call this method ever. + * + * @warning If you call this method from SDLManager's `startWithReadyHandler` be sure to wrap the `stop` call inside a dispatch_async and send it to the main queue or a global queue, otherwise calling `stop` may cause a deadlock. */ - (void)stop; diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m index 518877e96..9a66d81e4 100644 --- a/SmartDeviceLink/SDLTouchManager.m +++ b/SmartDeviceLink/SDLTouchManager.m @@ -227,8 +227,8 @@ static NSUInteger const MaximumNumberOfTouches = 2; self.currentPinchGesture = [[SDLPinchGesture alloc] initWithFirstTouch:self.previousTouch secondTouch:touch]; self.previousPinchDistance = self.currentPinchGesture.distance; if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidStartInView:atCenterPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; - [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:self.currentPinchGesture.center]; + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; + [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:self.currentPinchGesture.center]; } } break; } @@ -247,7 +247,7 @@ static NSUInteger const MaximumNumberOfTouches = 2; return; // no-op } #pragma clang diagnostic pop - + CGFloat xDelta = fabs(touch.location.x - self.firstTouch.location.x); CGFloat yDelta = fabs(touch.location.y - self.firstTouch.location.y); if (xDelta <= self.panDistanceThreshold && yDelta <= self.panDistanceThreshold) { @@ -275,8 +275,8 @@ static NSUInteger const MaximumNumberOfTouches = 2; _performingTouchType = SDLPerformingTouchTypePanningTouch; if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidStartInView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; - [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location]; + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; + [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location]; } } break; case SDLPerformingTouchTypePanningTouch: { @@ -302,9 +302,9 @@ static NSUInteger const MaximumNumberOfTouches = 2; [self sdl_setMultiTouchFingerTouchForTouch:touch]; if (self.currentPinchGesture.isValid) { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidEndInView:atCenterPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; - [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center]; - self.currentPinchGesture = nil; + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; + [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center]; + self.currentPinchGesture = nil; } else { self.currentPinchGesture = nil; } @@ -312,8 +312,8 @@ static NSUInteger const MaximumNumberOfTouches = 2; } break; case SDLPerformingTouchTypePanningTouch: { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidEndInView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; - [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location]; + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; + [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location]; } } break; case SDLPerformingTouchTypeSingleTouch: { @@ -333,8 +333,8 @@ static NSUInteger const MaximumNumberOfTouches = 2; CGPoint centerPoint = CGPointCenterOfPoints(touch.location, self.singleTapTouch.location); if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveDoubleTapForView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil; - [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint]; + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil; + [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint]; } } @@ -420,13 +420,37 @@ static NSUInteger const MaximumNumberOfTouches = 2; strongSelf.singleTapTouch = nil; [strongSelf sdl_cancelSingleTapTimer]; if ([strongSelf.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:point] : nil; - [strongSelf.touchEventDelegate touchManager:strongSelf didReceiveSingleTapForView:hitView atPoint:point]; + [self sdl_getSingleTapHitView:point hitViewHandler:^(UIView * _Nullable selectedView) { + [strongSelf.touchEventDelegate touchManager:strongSelf didReceiveSingleTapForView:selectedView atPoint:point]; + }]; } }); } /** + * HAX to preserve the thread on which the delegate is notified for single taps; returning on the main thread would be a breaking change. All other touch gestures currently notify the delegate on the main thread. The single tap timer runs on a background thread so when a single tap is detected the hit test needs to be done on the main thread and then the result is returned on a background thread. + * + * Checks if a single tap is inside a view. As the single tap timer is run on a background thread, the check is done on a main thread and then the result is returned on a background thread. + * + * @param point Screen coordinates of the tap gesture + * @param hitViewHandler A handler that returns the view the point is inside of; nil if the point does not lie inside of a view + */ +- (void)sdl_getSingleTapHitView:(CGPoint)point hitViewHandler:(nullable void (^)(UIView * __nullable hitView))hitViewHandler { + if (!self.hitTester) { + if (!hitViewHandler) { return; } + return hitViewHandler(nil); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = [self.hitTester viewForPoint:point]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + if (!hitViewHandler) { return; } + return hitViewHandler(hitView); + }); + }); +} + +/** * Cancels a tap gesture timer */ - (void)sdl_cancelSingleTapTimer { diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m index c7c339ac3..497870b9d 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m @@ -32,23 +32,23 @@ QuickSpecBegin(SDLHapticManagerSpec) describe(@"the haptic manager", ^{ __block UIWindow *uiWindow; __block UIViewController *uiViewController; - + __block SDLFocusableItemLocator *hapticManager; __block SDLSendHapticData* sentHapticRequest; - + __block id sdlLifecycleManager = OCMClassMock([SDLLifecycleManager class]); __block CGRect viewRect1; __block CGRect viewRect2; - + beforeEach(^{ hapticManager = nil; sentHapticRequest = nil; - + uiWindow = [[UIWindow alloc] init]; uiViewController = [[UIViewController alloc] init]; uiWindow.rootViewController = uiViewController; - + OCMExpect([[sdlLifecycleManager stub] sendConnectionManagerRequest:[OCMArg checkWithBlock:^BOOL(id value){ BOOL isFirstArg = [value isKindOfClass:[SDLSendHapticData class]]; if(isFirstArg) { @@ -75,216 +75,216 @@ describe(@"the haptic manager", ^{ expect(sentHapticRequest).to(beNil()); }); }); - + context(@"when initialized with no focusable view", ^{ beforeEach(^{ hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; [hapticManager updateInterfaceLayout]; }); - + it(@"should have no focusable view", ^{ OCMVerify(sdlLifecycleManager); expect(sentHapticRequest.hapticRectData.count).to(equal(0)); }); }); - + context(@"when initialized with single view", ^{ beforeEach(^{ viewRect1 = CGRectMake(101, 101, 50, 50); UITextField *textField1 = [[UITextField alloc] initWithFrame:viewRect1]; [uiViewController.view addSubview:textField1]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should have one view", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 1; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect = hapticRectData[0]; SDLRectangle *sdlRect = sdlhapticRect.rect; - + compareRectangle(sdlRect, viewRect1); } }); }); - + context(@"when initialized with single button view", ^{ beforeEach(^{ viewRect1 = CGRectMake(101, 101, 50, 50); UIButton *button = [[UIButton alloc] initWithFrame:viewRect1]; [uiViewController.view addSubview:button]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should have one view", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 1; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect = hapticRectData[0]; SDLRectangle *sdlRect = sdlhapticRect.rect; - + compareRectangle(sdlRect, viewRect1); } }); }); - + context(@"when initialized with no views and then updated with two additional views", ^{ beforeEach(^{ hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; - + viewRect1 = CGRectMake(101, 101, 50, 50); UITextField *textField1 = [[UITextField alloc] initWithFrame:viewRect1]; [uiViewController.view addSubview:textField1]; - + viewRect2 = CGRectMake(201, 201, 50, 50); UITextField *textField2 = [[UITextField alloc] initWithFrame:viewRect2]; [uiViewController.view addSubview:textField2]; - + [hapticManager updateInterfaceLayout]; }); - + it(@"should have two views", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 2; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect1 = hapticRectData[0]; SDLRectangle *sdlRect1 = sdlhapticRect1.rect; - + SDLHapticRect *sdlhapticRect2 = hapticRectData[1]; SDLRectangle *sdlRect2 = sdlhapticRect2.rect; - + compareRectangle(sdlRect1, viewRect2); compareRectangle(sdlRect2, viewRect1); } }); }); - + context(@"when initialized with nested views", ^{ beforeEach(^{ UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(101, 101, 50, 50)]; [uiViewController.view addSubview:textField]; - + viewRect1 = CGRectMake(110, 110, 10, 10); UITextField *textField1 = [[UITextField alloc] initWithFrame:viewRect1]; [textField addSubview:textField1]; - + viewRect2 = CGRectMake(130, 130, 10, 10); UITextField *textField2 = [[UITextField alloc] initWithFrame:viewRect2]; [textField addSubview:textField2]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should have only leaf views added", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 2; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect1 = hapticRectData[0]; SDLRectangle *sdlRect1 = sdlhapticRect1.rect; - + SDLHapticRect *sdlhapticRect2 = hapticRectData[1]; SDLRectangle *sdlRect2 = sdlhapticRect2.rect; - + compareRectangle(sdlRect1, viewRect1); compareRectangle(sdlRect2, viewRect2); } }); }); - + context(@"when initialized with nested button views", ^{ beforeEach(^{ UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(101, 101, 50, 50)]; [uiViewController.view addSubview:button]; - + viewRect1 = CGRectMake(110, 110, 10, 10); UIButton *button1 = [[UIButton alloc] initWithFrame:viewRect1]; [button addSubview:button1]; - + viewRect2 = CGRectMake(130, 130, 10, 10); UITextField *textField2 = [[UITextField alloc] initWithFrame:viewRect2]; [button addSubview:textField2]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should have only leaf views added", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 2; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect1 = hapticRectData[0]; SDLRectangle *sdlRect1 = sdlhapticRect1.rect; - + SDLHapticRect *sdlhapticRect2 = hapticRectData[1]; SDLRectangle *sdlRect2 = sdlhapticRect2.rect; - + compareRectangle(sdlRect1, viewRect1); compareRectangle(sdlRect2, viewRect2); } }); }); - + context(@"when initialized with two views and then updated with one view removed", ^{ beforeEach(^{ viewRect1 = CGRectMake(101, 101, 50, 50); UITextField *textField1 = [[UITextField alloc] initWithFrame:viewRect1]; [uiViewController.view addSubview:textField1]; - + viewRect2 = CGRectMake(201, 201, 50, 50); UITextField *textField2 = [[UITextField alloc] initWithFrame:viewRect2]; [uiViewController.view addSubview:textField2]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; - + [textField2 removeFromSuperview]; - + [hapticManager updateInterfaceLayout]; }); - + it(@"should have one view", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 1; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect = hapticRectData[0]; SDLRectangle *sdlRect = sdlhapticRect.rect; - + compareRectangle(sdlRect, viewRect1); } }); @@ -295,51 +295,51 @@ describe(@"the haptic manager", ^{ viewRect1 = CGRectMake(101, 101, 50, 50); UITextField *textField1 = [[UITextField alloc] initWithFrame:viewRect1]; [uiViewController.view addSubview:textField1]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; - + viewRect2 = CGRectMake(201, 201, 50, 50); UITextField *textField2 = [[UITextField alloc] initWithFrame:viewRect2]; [uiViewController.view addSubview:textField2]; - + [[NSNotificationCenter defaultCenter] postNotificationName:SDLDidUpdateProjectionView object:nil]; }); - + it(@"should have two views", ^{ OCMVerify(sdlLifecycleManager); - + int expectedCount = 2; expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount)); - + if(sentHapticRequest.hapticRectData.count == expectedCount) { NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData; SDLHapticRect *sdlhapticRect1 = hapticRectData[0]; SDLRectangle *sdlRect1 = sdlhapticRect1.rect; - + SDLHapticRect *sdlhapticRect2 = hapticRectData[1]; SDLRectangle *sdlRect2 = sdlhapticRect2.rect; - + compareRectangle(sdlRect1, viewRect2); compareRectangle(sdlRect2, viewRect1); } }); }); - + context(@"when touched inside a view", ^{ beforeEach(^{ UITextField *textField1 = [[UITextField alloc] initWithFrame:CGRectMake(101, 101, 50, 50)]; [uiViewController.view addSubview:textField1]; - + UITextField *textField2 = [[UITextField alloc] initWithFrame:CGRectMake(201, 201, 50, 50)]; [uiViewController.view addSubview:textField2]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should return a view object", ^{ UIView *view1 = [hapticManager viewForPoint:CGPointMake(125, 120)]; expect(view1).toNot(beNil()); @@ -348,31 +348,31 @@ describe(@"the haptic manager", ^{ expect(view2).toNot(beNil()); }); }); - + context(@"when touched in overlapping views' area", ^{ beforeEach(^{ UITextField *textField1 = [[UITextField alloc] initWithFrame:CGRectMake(101, 101, 50, 50)]; [uiViewController.view addSubview:textField1]; - + UITextField *textField2 = [[UITextField alloc] initWithFrame:CGRectMake(126, 126, 50, 50)]; [uiViewController.view addSubview:textField2]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; }); - + it(@"should return no view object", ^{ UIView* view = [hapticManager viewForPoint:CGPointMake(130, 130)]; expect(view).to(beNil()); }); }); - + context(@"when touched outside view boundary", ^{ beforeEach(^{ UITextField *textField1 = [[UITextField alloc] initWithFrame:CGRectMake(101, 101, 50, 50)]; [uiWindow insertSubview:textField1 aboveSubview:uiWindow]; - + hapticManager = [[SDLFocusableItemLocator alloc] initWithViewController:uiViewController connectionManager:sdlLifecycleManager]; hapticManager.enableHapticDataRequests = YES; [hapticManager updateInterfaceLayout]; @@ -381,7 +381,7 @@ describe(@"the haptic manager", ^{ UIView* view = [hapticManager viewForPoint:CGPointMake(0, 228)]; expect(view).to(beNil()); }); - + }); }); |