From 0a07c8d9388280a8fe614e787ecdc4c61f5f3d5b Mon Sep 17 00:00:00 2001 From: Mark Granoff Date: Sat, 8 Aug 2015 17:45:33 -0400 Subject: [PATCH 1/4] Add phone number detection. --- KILabel/Source/KILabel.h | 19 ++++++- KILabel/Source/KILabel.m | 54 +++++++++++++------ .../KILabelDemo/Base.lproj/Main.storyboard | 27 +++++++--- .../KILabelDemo/KILabelTableViewController.m | 5 ++ KILabelDemo/KILabelDemo/KIViewController.m | 28 ++++++++++ 5 files changed, 109 insertions(+), 24 deletions(-) diff --git a/KILabel/Source/KILabel.h b/KILabel/Source/KILabel.h index 74c6cc6..b9f0f82 100644 --- a/KILabel/Source/KILabel.h +++ b/KILabel/Source/KILabel.h @@ -35,7 +35,7 @@ typedef NS_ENUM(NSUInteger, KILinkType) /** * Usernames starting with "@" token */ - KILinkTypeUserHandle, + KILinkTypeUserHandle = 0, /** * Hashtags starting with "#" token @@ -46,6 +46,11 @@ typedef NS_ENUM(NSUInteger, KILinkType) * URLs, http etc */ KILinkTypeURL, + + /** + * Phone numbers + */ + KILinkTypePhoneNumber }; /** @@ -73,6 +78,11 @@ typedef NS_OPTIONS(NSUInteger, KILinkTypeOption) */ KILinkTypeOptionURL = 1 << KILinkTypeURL, + /** + * Specified to include KILinkTypePhoneNumber links + */ + KILinkTypeOptionPhoneNumber = 1 << KILinkTypePhoneNumber, + /** * Convenience contstant to include all link types */ @@ -107,7 +117,7 @@ IB_DESIGNABLE ** ****************************************************************************************** **/ /** - * Enable/disable automatic detection of links, hashtags and usernames. + * Enable/disable automatic detection of links, hashtags, usernames, and phone numbers. */ @property (nonatomic, assign, getter = isAutomaticLinkDetectionEnabled) IBInspectable BOOL automaticLinkDetectionEnabled; @@ -176,6 +186,11 @@ IB_DESIGNABLE */ @property (nullable, nonatomic, copy) KILinkTapHandler urlLinkTapHandler; +/** + * Callback block for KILinkTypePhoneNumber link tap. + */ +@property (nullable, nonatomic, copy) KILinkTapHandler phoneNumberLinkTapHandler; + /** ****************************************************************************************** ** * @name Geometry ** ****************************************************************************************** **/ diff --git a/KILabel/Source/KILabel.m b/KILabel/Source/KILabel.m index 37dbbff..745624d 100644 --- a/KILabel/Source/KILabel.m +++ b/KILabel/Source/KILabel.m @@ -388,6 +388,11 @@ - (NSArray *)getRangesForLinks:(NSAttributedString *)text [rangesForLinks addObjectsFromArray:[self getRangesForURLs:self.attributedText]]; } + if (self.linkDetectionTypes & KILinkTypeOptionPhoneNumber) + { + [rangesForLinks addObjectsFromArray:[self getRangesForPhoneNumbers:self.attributedText]]; + } + return rangesForLinks; } @@ -457,14 +462,13 @@ - (NSArray *)getRangesForHashtags:(NSString *)text return rangesForHashtags; } - -- (NSArray *)getRangesForURLs:(NSAttributedString *)text +- (NSArray *)_getRangesForDetectorType:(NSTextCheckingTypes)detectorType usingLinkType:(KILinkType)linkType forText:(NSAttributedString *)text { - NSMutableArray *rangesForURLs = [[NSMutableArray alloc] init];; + NSMutableArray *ranges = [[NSMutableArray alloc] init]; - // Use a data detector to find urls in the text + // Use a data detector to mathing text NSError *error = nil; - NSDataDetector *detector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error]; + NSDataDetector *detector = [[NSDataDetector alloc] initWithTypes:detectorType error:&error]; NSString *plainText = text.string; @@ -478,23 +482,34 @@ - (NSArray *)getRangesForURLs:(NSAttributedString *)text NSRange matchRange = [match range]; // If there's a link embedded in the attributes, use that instead of the raw text - NSString *realURL = [text attribute:NSLinkAttributeName atIndex:matchRange.location effectiveRange:nil]; - if (realURL == nil) - realURL = [plainText substringWithRange:matchRange]; + NSString *realText = [text attribute:NSLinkAttributeName atIndex:matchRange.location effectiveRange:nil]; + if (realText == nil) + realText = [plainText substringWithRange:matchRange]; - if (![self ignoreMatch:realURL]) + if (![self ignoreMatch:realText]) { - if ([match resultType] == NSTextCheckingTypeLink) + if ([match resultType] == detectorType) { - [rangesForURLs addObject:@{KILabelLinkTypeKey : @(KILinkTypeURL), + [ranges addObject:@{KILabelLinkTypeKey : @(linkType), KILabelRangeKey : [NSValue valueWithRange:matchRange], - KILabelLinkKey : realURL, - }]; + KILabelLinkKey : realText, + }]; } } } - return rangesForURLs; + return ranges; + +} + +- (NSArray *)getRangesForURLs:(NSAttributedString *)text +{ + return [self _getRangesForDetectorType:NSTextCheckingTypeLink usingLinkType:KILinkTypeURL forText:text]; +} + +- (NSArray *)getRangesForPhoneNumbers:(NSAttributedString *)text +{ + return [self _getRangesForDetectorType:NSTextCheckingTypePhoneNumber usingLinkType:KILinkTypePhoneNumber forText:text]; } - (BOOL)ignoreMatch:(NSString*)string @@ -516,8 +531,8 @@ - (NSAttributedString *)addLinkAttributesToAttributedString:(NSAttributedString // Use our tint color to hilight the link [attributedString addAttributes:attributes range:range]; - // Add an URL attribute if this is a URL - if (_systemURLStyle && ((KILinkType)[dictionary[KILabelLinkTypeKey] unsignedIntegerValue] == KILinkTypeURL)) + // Add an URL attribute if this is a URL or phone number + if (_systemURLStyle && (linkType == KILinkTypeURL)) { // Add a link attribute using the stored link [attributedString addAttribute:NSLinkAttributeName value:dictionary[KILabelLinkKey] range:range]; @@ -721,6 +736,13 @@ - (void)receivedActionForLinkType:(KILinkType)linkType string:(NSString*)string _urlLinkTapHandler(self, string, range); } break; + + case KILinkTypePhoneNumber: + if (_phoneNumberLinkTapHandler) + { + _phoneNumberLinkTapHandler(self, string, range); + } + break; } } diff --git a/KILabelDemo/KILabelDemo/Base.lproj/Main.storyboard b/KILabelDemo/KILabelDemo/Base.lproj/Main.storyboard index 1279791..1e6dea9 100644 --- a/KILabelDemo/KILabelDemo/Base.lproj/Main.storyboard +++ b/KILabelDemo/KILabelDemo/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -16,8 +16,8 @@ -