Ipad 仅在iOS 8上的Modal UIViewController内检测到UIAPTgestureRecognitor
我一直在尝试实现一个UITapGestureRecognitor,它通过检测iOS 8上模式视图控制器外部的点击来关闭模式视图控制器 我看到的问题是,在iPad的横向模式下,点击手势只能在视图控制器的内部识别。我的模态视图是380宽x 550高。当方向处于横向(主页按钮位于右侧)时,会在模式视图的下半部分内检测到点击手势。当方向为横向,但主页按钮位于左侧时,会在模式视图的上半部分内检测到点击手势 问题1:点击手势仅在模态视图内部检测到,而应在外部检测到。 问题2:在横向视图的某些区域中未检测到 以下是我使用的代码: UIViewController+DismissOntaOutside.hIpad 仅在iOS 8上的Modal UIViewController内检测到UIAPTgestureRecognitor,ipad,ios8,uigesturerecognizer,modalviewcontroller,landscape,Ipad,Ios8,Uigesturerecognizer,Modalviewcontroller,Landscape,我一直在尝试实现一个UITapGestureRecognitor,它通过检测iOS 8上模式视图控制器外部的点击来关闭模式视图控制器 我看到的问题是,在iPad的横向模式下,点击手势只能在视图控制器的内部识别。我的模态视图是380宽x 550高。当方向处于横向(主页按钮位于右侧)时,会在模式视图的下半部分内检测到点击手势。当方向为横向,但主页按钮位于左侧时,会在模式视图的上半部分内检测到点击手势 问题1:点击手势仅在模态视图内部检测到,而应在外部检测到。 问题2:在横向视图的某些区域中未检测到
#import <UIKit/UIKit.h>
@interface UIViewController (DismissOnTapOutside)
- (void)registerForDismissOnTapOutside; // Call in viewDidAppear
- (void)unregisterForDismissOnTapOutside; // Call in viewWillDisappear
@end
我在StackOverflow上看到的与此问题相关的所有示例都坚信上述代码是有效的。但在我的例子中,它根本没有检测到模态视图控制器外部的点击
在iPad的iOS 8中,如何在横向方向上检测到模式外的点击
#import "UIViewController+DismissOnTapOutside.h"
#import <objc/runtime.h>
static char gestureRecognizerKey;
static char gestureRecognizerDelegateKey;
@interface SimpleGestureRecognizerDelegate : NSObject <UIGestureRecognizerDelegate>
@end
@implementation SimpleGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return [otherGestureRecognizer isMemberOfClass:[UITapGestureRecognizer class]];
}
@end
@interface UIViewController ()
@property (assign, nonatomic) UIGestureRecognizer *gestureRecognizer;
@property (strong, nonatomic) SimpleGestureRecognizerDelegate *gestureRecognizerDelegate;
@end
@implementation UIViewController (DismissOnTapOutside)
- (void)setGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
objc_setAssociatedObject(self, &gestureRecognizerKey, gestureRecognizer, OBJC_ASSOCIATION_ASSIGN);
}
- (UIGestureRecognizer *)gestureRecognizer
{
return objc_getAssociatedObject(self, &gestureRecognizerKey);
}
- (void)setGestureRecognizerDelegate:(SimpleGestureRecognizerDelegate *)delegate
{
objc_setAssociatedObject(self, &gestureRecognizerDelegateKey, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIGestureRecognizer *)gestureRecognizerDelegate
{
id delegate = objc_getAssociatedObject(self, &gestureRecognizerDelegateKey);
if (!delegate)
{
delegate = [[SimpleGestureRecognizerDelegate alloc] init];
self.gestureRecognizerDelegate = delegate;
}
return delegate;
}
- (void)handleDismissTap:(UIGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateEnded)
{
UIView *view = self.navigationController.view ?: self.view;
// Passing nil gives us coordinates in the window
CGPoint location = [gesture locationInView:nil];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
location = CGPointMake(location.y, location.x);
}
}
// Then we convert the tap's location into the local view's coordinate system
location = [view convertPoint:location fromView:self.view.window];
if (![view pointInside:location withEvent:nil])
{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
}
}
- (void)registerForDismissOnTapOutside
{
// This approach is attributed to Danilo Campos:
// http://stackoverflow.com/a/6180584/456434
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissTap:)];
recognizer.delegate = self.gestureRecognizerDelegate;
recognizer.numberOfTapsRequired = 1;
recognizer.cancelsTouchesInView = NO;
self.gestureRecognizer = recognizer;
[self.view.window addGestureRecognizer:recognizer];
}
- (void)unregisterForDismissOnTapOutside
{
[self.view.window removeGestureRecognizer:self.gestureRecognizer];
self.gestureRecognizer = nil;
}
@end
- (void)handleDismissTap:(UIGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateEnded)
{
UIView *view = self.navigationController.view ?: self.view;
// Passing nil gives us coordinates in the window
CGPoint location = [gesture locationInView:nil];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
location = CGPointMake(location.y, location.x);
}
}
// Then we convert the tap's location into the local view's coordinate system
location = [view convertPoint:location fromView:self.view.window];
if (![view pointInside:location withEvent:nil])
{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
}
}