mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			133 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Objective-C
		
	
//
 | 
						|
//  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#import "OWSAnyTouchGestureRecognizer.h"
 | 
						|
#import <UIKit/UIGestureRecognizerSubclass.h>
 | 
						|
 | 
						|
NS_ASSUME_NONNULL_BEGIN
 | 
						|
 | 
						|
NSString *NSStringForUIGestureRecognizerState(UIGestureRecognizerState state)
 | 
						|
{
 | 
						|
    switch (state) {
 | 
						|
        case UIGestureRecognizerStatePossible:
 | 
						|
            return @"UIGestureRecognizerStatePossible";
 | 
						|
        case UIGestureRecognizerStateBegan:
 | 
						|
            return @"UIGestureRecognizerStateBegan";
 | 
						|
        case UIGestureRecognizerStateChanged:
 | 
						|
            return @"UIGestureRecognizerStateChanged";
 | 
						|
        case UIGestureRecognizerStateEnded:
 | 
						|
            return @"UIGestureRecognizerStateEnded";
 | 
						|
        case UIGestureRecognizerStateCancelled:
 | 
						|
            return @"UIGestureRecognizerStateCancelled";
 | 
						|
        case UIGestureRecognizerStateFailed:
 | 
						|
            return @"UIGestureRecognizerStateFailed";
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
@implementation OWSAnyTouchGestureRecognizer
 | 
						|
 | 
						|
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
 | 
						|
{
 | 
						|
    return NO;
 | 
						|
}
 | 
						|
 | 
						|
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
 | 
						|
{
 | 
						|
    return NO;
 | 
						|
}
 | 
						|
 | 
						|
- (BOOL)shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 | 
						|
{
 | 
						|
    return NO;
 | 
						|
}
 | 
						|
 | 
						|
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 | 
						|
{
 | 
						|
    return YES;
 | 
						|
}
 | 
						|
 | 
						|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 | 
						|
{
 | 
						|
    [super touchesBegan:touches withEvent:event];
 | 
						|
 | 
						|
    if (self.state == UIGestureRecognizerStatePossible && [self isValidTouch:touches event:event]) {
 | 
						|
        self.state = UIGestureRecognizerStateRecognized;
 | 
						|
    } else {
 | 
						|
        self.state = UIGestureRecognizerStateFailed;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
- (UIView *)rootViewInViewHierarchy:(UIView *)view
 | 
						|
{
 | 
						|
    OWSAssertDebug(view);
 | 
						|
    UIResponder *responder = view;
 | 
						|
    UIView *lastView = nil;
 | 
						|
    while (responder) {
 | 
						|
        if ([responder isKindOfClass:[UIView class]]) {
 | 
						|
            lastView = (UIView *)responder;
 | 
						|
        }
 | 
						|
        responder = [responder nextResponder];
 | 
						|
    }
 | 
						|
    return lastView;
 | 
						|
}
 | 
						|
 | 
						|
- (BOOL)isValidTouch:(NSSet<UITouch *> *)touches event:(UIEvent *)event
 | 
						|
{
 | 
						|
    if (event.allTouches.count > 1) {
 | 
						|
        return NO;
 | 
						|
    }
 | 
						|
    if (touches.count != 1) {
 | 
						|
        return NO;
 | 
						|
    }
 | 
						|
 | 
						|
    UITouch *touch = touches.anyObject;
 | 
						|
    CGPoint location = [touch locationInView:self.view];
 | 
						|
    if (!CGRectContainsPoint(self.view.bounds, location)) {
 | 
						|
        return NO;
 | 
						|
    }
 | 
						|
 | 
						|
    if ([self subviewControlOfView:self.view containsTouch:touch]) {
 | 
						|
        return NO;
 | 
						|
    }
 | 
						|
 | 
						|
    // Ignore touches that start near the top or bottom edge of the screen;
 | 
						|
    // they may be a system edge swipe gesture.
 | 
						|
    UIView *rootView = [self rootViewInViewHierarchy:self.view];
 | 
						|
    CGPoint rootLocation = [touch locationInView:rootView];
 | 
						|
    CGFloat distanceToTopEdge = MAX(0, rootLocation.y);
 | 
						|
    CGFloat distanceToBottomEdge = MAX(0, rootView.bounds.size.height - rootLocation.y);
 | 
						|
    CGFloat distanceToNearestEdge = MIN(distanceToTopEdge, distanceToBottomEdge);
 | 
						|
    CGFloat kSystemEdgeSwipeTolerance = 50.f;
 | 
						|
    if (distanceToNearestEdge < kSystemEdgeSwipeTolerance) {
 | 
						|
        return NO;
 | 
						|
    }
 | 
						|
 | 
						|
    return YES;
 | 
						|
}
 | 
						|
 | 
						|
- (BOOL)subviewControlOfView:(UIView *)superview containsTouch:(UITouch *)touch
 | 
						|
{
 | 
						|
    for (UIView *subview in superview.subviews) {
 | 
						|
        if (subview.hidden || !subview.userInteractionEnabled) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        CGPoint location = [touch locationInView:subview];
 | 
						|
        if (!CGRectContainsPoint(subview.bounds, location)) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        if ([subview isKindOfClass:[UIControl class]]) {
 | 
						|
            return YES;
 | 
						|
        }
 | 
						|
        if ([self subviewControlOfView:subview containsTouch:touch]) {
 | 
						|
            return YES;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return NO;
 | 
						|
}
 | 
						|
 | 
						|
@end
 | 
						|
 | 
						|
NS_ASSUME_NONNULL_END
 |