diff --git a/CCHLinkTextView Example/CCHLinkTextView ExampleTests/CCHLinkTextViewTests.m b/CCHLinkTextView Example/CCHLinkTextView ExampleTests/CCHLinkTextViewTests.m index 60493f7..6b79a94 100644 --- a/CCHLinkTextView Example/CCHLinkTextView ExampleTests/CCHLinkTextViewTests.m +++ b/CCHLinkTextView Example/CCHLinkTextView ExampleTests/CCHLinkTextViewTests.m @@ -44,34 +44,6 @@ self.linkTextView.text = @"012345678901234567890123456789"; } -- (void)testLinkRangeFound -{ - NSRange range = NSMakeRange(3, 4); - [self.linkTextView addLinkForRange:range]; - - __block NSUInteger blockCalled = 0; - BOOL linkFound = [self.linkTextView enumerateLinkRangesIncludingCharacterIndex:4 usingBlock:^(NSRange range) { - blockCalled++; - }]; - - XCTAssertTrue(linkFound); - XCTAssertEqual(blockCalled, 1u); -} - -- (void)testLinkRangeNotFound -{ - NSRange range = NSMakeRange(3, 4); - [self.linkTextView addLinkForRange:range]; - - __block NSUInteger blockCalled = 0; - BOOL linkFound = [self.linkTextView enumerateLinkRangesIncludingCharacterIndex:1 usingBlock:^(NSRange range) { - blockCalled++; - }]; - - XCTAssertFalse(linkFound); - XCTAssertEqual(blockCalled, 0u); -} - - (void)testEnumerateViewRectsForRanges { NSValue *rangeAsValue = [NSValue valueWithRange:NSMakeRange(0, 10)]; @@ -109,7 +81,7 @@ [self.linkTextView addLinkForRange:linkRange]; __block NSUInteger blockCalled = 0; - [self.linkTextView enumerateLinkRangesContainingPoint:CGPointMake(50, 20) usingBlock:^(NSRange range) { + [self.linkTextView enumerateLinkRangesContainingLocation:CGPointMake(50, 20) usingBlock:^(NSRange range) { blockCalled++; XCTAssertTrue(NSEqualRanges(range, linkRange)); }]; @@ -122,7 +94,7 @@ [self.linkTextView addLinkForRange:linkRange]; __block NSUInteger blockCalled = 0; - [self.linkTextView enumerateLinkRangesContainingPoint:CGPointMake(50, 20) usingBlock:^(NSRange range) { + [self.linkTextView enumerateLinkRangesContainingLocation:CGPointMake(50, 20) usingBlock:^(NSRange range) { blockCalled++; XCTAssertTrue(NSEqualRanges(range, linkRange)); }]; @@ -135,7 +107,7 @@ [self.linkTextView addLinkForRange:NSMakeRange(5, 20)]; __block NSUInteger blockCalled = 0; - [self.linkTextView enumerateLinkRangesContainingPoint:CGPointMake(50, 20) usingBlock:^(NSRange range) { + [self.linkTextView enumerateLinkRangesContainingLocation:CGPointMake(50, 20) usingBlock:^(NSRange range) { blockCalled++; }]; XCTAssertEqual(blockCalled, 2); diff --git a/CCHLinkTextView/CCHLinkTextView.h b/CCHLinkTextView/CCHLinkTextView.h index cb577db..70345d7 100644 --- a/CCHLinkTextView/CCHLinkTextView.h +++ b/CCHLinkTextView/CCHLinkTextView.h @@ -39,8 +39,8 @@ - (void)addLinkForRange:(NSRange)range; //- (void)removeLinkForRange:(NSRange)range; -- (BOOL)enumerateLinkRangesIncludingCharacterIndex:(NSUInteger)characterIndex usingBlock:(void (^)(NSRange range))block; + - (void)enumerateViewRectsForRanges:(NSArray *)ranges usingBlock:(void (^)(CGRect rect, NSRange range, BOOL *stop))block; -- (BOOL)enumerateLinkRangesContainingPoint:(CGPoint)point usingBlock:(void (^)(NSRange range))block; +- (BOOL)enumerateLinkRangesContainingLocation:(CGPoint)location usingBlock:(void (^)(NSRange range))block; @end diff --git a/CCHLinkTextView/CCHLinkTextView.m b/CCHLinkTextView/CCHLinkTextView.m index 6d4217f..bd5c4ec 100644 --- a/CCHLinkTextView/CCHLinkTextView.m +++ b/CCHLinkTextView/CCHLinkTextView.m @@ -35,7 +35,7 @@ @interface CCHLinkTextView () @property (nonatomic, strong) NSMutableArray *linkRanges; -@property (nonatomic, assign) NSUInteger touchDownCharacterIndex; +@property (nonatomic, assign) CGPoint touchDownLocation; @property (nonatomic, strong) CCHLinkGestureRecognizer *linkGestureRecognizer; @end @@ -59,18 +59,13 @@ - (void)setUp { self.linkRanges = [NSMutableArray array]; - self.touchDownCharacterIndex = -1; + self.touchDownLocation = CGPointZero; self.linkGestureRecognizer = [[CCHLinkGestureRecognizer alloc] initWithTarget:self action:@selector(linkAction:)]; self.linkGestureRecognizer.delegate = self; [self addGestureRecognizer:self.linkGestureRecognizer]; } -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - return YES; -} - - (void)addLinkForRange:(NSRange)range { [self.linkRanges addObject:[NSValue valueWithRange:range]]; @@ -93,7 +88,7 @@ UIGraphicsPopContext(); } -- (BOOL)enumerateLinkRangesContainingPoint:(CGPoint)point usingBlock:(void (^)(NSRange range))block +- (BOOL)enumerateLinkRangesContainingLocation:(CGPoint)location usingBlock:(void (^)(NSRange range))block { if (!block) { return NO; @@ -101,7 +96,7 @@ __block BOOL found = NO; [self enumerateViewRectsForRanges:self.linkRanges usingBlock:^(CGRect rect, NSRange range, BOOL *stop) { - if (CGRectContainsPoint(rect, point)) { + if (CGRectContainsPoint(rect, location)) { found = YES; *stop = YES; block(range); @@ -129,35 +124,6 @@ } } -- (BOOL)enumerateLinkRangesIncludingCharacterIndex:(NSUInteger)characterIndex usingBlock:(void (^)(NSRange range))block -{ - if (!block) { - return NO; - } - - BOOL linkTapped = NO; - - for (NSValue *value in self.linkRanges) { - NSRange range = value.rangeValue; - if (NSLocationInRange(characterIndex, range)) { - linkTapped = YES; - block(range); - } - } - - return linkTapped; -} - -- (NSUInteger)characterIndexForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer -{ - CGPoint location = [gestureRecognizer locationInView:self]; - location.x -= self.textContainerInset.left; - location.y -= self.textContainerInset.top; - - NSUInteger characterIndex = [self.layoutManager characterIndexForPoint:location inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:NULL]; - return characterIndex; -} - - (void)addAttributes:(NSDictionary *)attributes range:(NSRange)range { NSMutableAttributedString *attributedText = [self.attributedText mutableCopy]; @@ -190,53 +156,60 @@ - (void)linkAction:(CCHLinkGestureRecognizer *)recognizer { if (recognizer.state == UIGestureRecognizerStateBegan) { - NSAssert(self.touchDownCharacterIndex == -1, @"Invalid character index"); - self.touchDownCharacterIndex = [self characterIndexForGestureRecognizer:recognizer]; - [self didTouchDownAtCharacterIndex:self.touchDownCharacterIndex]; + NSAssert(CGPointEqualToPoint(self.touchDownLocation, CGPointZero), @"Invalid touch down location"); + + CGPoint location = [recognizer locationInView:self]; + self.touchDownLocation = location; + [self didTouchDownAtLocation:location]; } else if (recognizer.state == UIGestureRecognizerStateEnded) { - NSAssert(self.touchDownCharacterIndex != -1, @"Invalid character index"); - NSUInteger characterIndex = self.touchDownCharacterIndex; + NSAssert(!CGPointEqualToPoint(self.touchDownLocation, CGPointZero), @"Invalid touch down location"); - if (recognizer.result == CCHLinkGestureRecognizerResultTap) { - BOOL linkFound = [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { - [self didTapLinkAtCharacterIndex:characterIndex range:range]; - }]; - - if (!linkFound) { - [self linkTextViewDidTap]; - } - } else if (recognizer.result == CCHLinkGestureRecognizerResultLongPress) { - BOOL linkFound = [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { - [self didLongPressLinkAtCharacterIndex:characterIndex range:range]; - }]; - - if (!linkFound) { - [self linkTextViewDidLongPress]; - } - } + CGPoint location = self.touchDownLocation; +// if (recognizer.result == CCHLinkGestureRecognizerResultTap) { +// BOOL linkFound = [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { +// [self didTapLinkAtCharacterIndex:characterIndex range:range]; +// }]; +// +// if (!linkFound) { +// [self linkTextViewDidTap]; +// } +// } else if (recognizer.result == CCHLinkGestureRecognizerResultLongPress) { +// BOOL linkFound = [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { +// [self didLongPressLinkAtCharacterIndex:characterIndex range:range]; +// }]; +// +// if (!linkFound) { +// [self linkTextViewDidLongPress]; +// } +// } - [self didCancelTouchDownAtCharacterIndex:characterIndex]; - self.touchDownCharacterIndex = -1; + [self didCancelTouchDownAtLocation:location]; + self.touchDownLocation = CGPointZero; } } +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return YES; +} + #pragma mark Gesture handling -- (void)didTouchDownAtCharacterIndex:(NSUInteger)characterIndex +- (void)didTouchDownAtLocation:(CGPoint)location { - NSLog(@"touch down %tu", characterIndex); + NSLog(@"touch down"); - [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { + [self enumerateLinkRangesContainingLocation:location usingBlock:^(NSRange range) { NSDictionary *attributes = @{NSBackgroundColorAttributeName : UIColor.greenColor}; [self addAttributes:attributes range:range]; }]; } -- (void)didCancelTouchDownAtCharacterIndex:(NSUInteger)characterIndex +- (void)didCancelTouchDownAtLocation:(CGPoint)location { - NSLog(@"touch down canceled %tu", characterIndex); + NSLog(@"touch down canceled"); - [self enumerateLinkRangesIncludingCharacterIndex:characterIndex usingBlock:^(NSRange range) { + [self enumerateLinkRangesContainingLocation:location usingBlock:^(NSRange range) { NSDictionary *attributes = @{NSBackgroundColorAttributeName : UIColor.clearColor}; [self addAttributes:attributes range:range]; }];