From d2d966cde715c695ff9d86c138cd0f2fed3c8c1a Mon Sep 17 00:00:00 2001 From: "Carlos Oliva (MBA)" Date: Tue, 9 Jun 2015 19:01:19 -0300 Subject: [PATCH 1/4] Random crash fix on -attributesFromProperties Checks for nil values before constructing and returning the attributes dict --- KILabel/Source/KILabel.m | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/KILabel/Source/KILabel.m b/KILabel/Source/KILabel.m index 37dbbff..0249c08 100644 --- a/KILabel/Source/KILabel.m +++ b/KILabel/Source/KILabel.m @@ -353,12 +353,20 @@ - (NSDictionary *)attributesFromProperties paragraph.alignment = self.textAlignment; // Create the dictionary - NSDictionary *attributes = @{NSFontAttributeName : self.font, - NSForegroundColorAttributeName : color, - NSShadowAttributeName : shadow, - NSParagraphStyleAttributeName : paragraph, - }; - return attributes; + NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; + if(self.font != nil) { + [attributes setObject:self.font forKey:NSFontAttributeName]; + } + if(color != nil) { + [attributes setObject:color forKey:NSForegroundColorAttributeName]; + } + if(shadow != nil) { + [attributes setObject:shadow forKey:NSShadowAttributeName]; + } + if(paragraph != nil) { + [attributes setObject:paragraph forKey:NSParagraphStyleAttributeName]; + } + return [attributes copy]; } /** From 75bbca0400f1a4a6f302426321f9d397c590a35e Mon Sep 17 00:00:00 2001 From: "Carlos Oliva (MBA)" Date: Thu, 25 Jun 2015 16:06:30 -0300 Subject: [PATCH 2/4] Added Protocol to conditionally ignore keywords for each type --- KILabel/Source/KILabel.h | 19 +++++++++++++++++++ KILabel/Source/KILabel.m | 27 ++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/KILabel/Source/KILabel.h b/KILabel/Source/KILabel.h index 74c6cc6..78a1edb 100644 --- a/KILabel/Source/KILabel.h +++ b/KILabel/Source/KILabel.h @@ -27,6 +27,20 @@ NS_ASSUME_NONNULL_BEGIN +@class KILabel; + +@protocol KILabelDelegate + +@optional + +- (BOOL)label:(KILabel *)label shouldIgnoreUserHandle:(NSString *)userHandle; +- (BOOL)label:(KILabel *)label shouldIgnoreHashtag:(NSString *)hashtag; +- (BOOL)label:(KILabel *)label shouldIgnoreURL:(NSURL *)URL; + + +@end + + /** * Constants for identifying link types we can detect */ @@ -123,6 +137,11 @@ IB_DESIGNABLE */ @property (nullable, nonatomic, strong) NSSet *ignoredKeywords; +/** + * Optionally, assign a delegate to query for usernames/hashtags/URLs to be ignored + */ +@property (nullable, nonatomic, weak) id delegate; + /** ****************************************************************************************** ** * @name Format & Appearance ** ****************************************************************************************** **/ diff --git a/KILabel/Source/KILabel.m b/KILabel/Source/KILabel.m index 0249c08..ead6b3e 100644 --- a/KILabel/Source/KILabel.m +++ b/KILabel/Source/KILabel.m @@ -420,7 +420,7 @@ - (NSArray *)getRangesForUserHandles:(NSString *)text NSRange matchRange = [match range]; NSString *matchString = [text substringWithRange:matchRange]; - if (![self ignoreMatch:matchString]) + if (![self ignoreMatch:matchString] && ![self shouldIgnoreUserHandle:matchString]) { [rangesForUserHandles addObject:@{KILabelLinkTypeKey : @(KILinkTypeUserHandle), KILabelRangeKey : [NSValue valueWithRange:matchRange], @@ -453,7 +453,7 @@ - (NSArray *)getRangesForHashtags:(NSString *)text NSRange matchRange = [match range]; NSString *matchString = [text substringWithRange:matchRange]; - if (![self ignoreMatch:matchString]) + if (![self ignoreMatch:matchString] && ![self shouldIgnoreHashtag:matchString]) { [rangesForHashtags addObject:@{KILabelLinkTypeKey : @(KILinkTypeHashtag), KILabelRangeKey : [NSValue valueWithRange:matchRange], @@ -490,7 +490,7 @@ - (NSArray *)getRangesForURLs:(NSAttributedString *)text if (realURL == nil) realURL = [plainText substringWithRange:matchRange]; - if (![self ignoreMatch:realURL]) + if (![self ignoreMatch:realURL] && ![self shouldIgnoreURL:[NSURL URLWithString:realURL]]) { if ([match resultType] == NSTextCheckingTypeLink) { @@ -510,6 +510,27 @@ - (BOOL)ignoreMatch:(NSString*)string return [_ignoredKeywords containsObject:[string lowercaseString]]; } +- (BOOL)shouldIgnoreUserHandle:(NSString *)userHandle { + if(self.delegate != nil && [self.delegate respondsToSelector:@selector(label:shouldIgnoreUserHandle:)]) { + return [self.delegate label:self shouldIgnoreUserHandle:userHandle]; + } + return NO; +} + +- (BOOL)shouldIgnoreHashtag:(NSString *)hashtag { + if(self.delegate != nil && [self.delegate respondsToSelector:@selector(label:shouldIgnoreHashtag:)]) { + return [self.delegate label:self shouldIgnoreHashtag:hashtag]; + } + return NO; +} + +- (BOOL)shouldIgnoreURL:(NSURL *)URL { + if(self.delegate != nil && [self.delegate respondsToSelector:@selector(label:shouldIgnoreURL:)]) { + return [self.delegate label:self shouldIgnoreURL:URL]; + } + return NO; +} + - (NSAttributedString *)addLinkAttributesToAttributedString:(NSAttributedString *)string linkRanges:(NSArray *)linkRanges { NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:string]; From a51d0b1a5c2c57ceac1602900e4f526eaac8e5f2 Mon Sep 17 00:00:00 2001 From: "Carlos Oliva (MBA)" Date: Wed, 22 Jun 2016 02:13:28 -0400 Subject: [PATCH 3/4] Handle NSLinkAttributeName returning a NSURL object instead of NSString --- KILabel/Source/KILabel.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/KILabel/Source/KILabel.m b/KILabel/Source/KILabel.m index ead6b3e..0f8a151 100644 --- a/KILabel/Source/KILabel.m +++ b/KILabel/Source/KILabel.m @@ -486,11 +486,10 @@ - (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]; - - if (![self ignoreMatch:realURL] && ![self shouldIgnoreURL:[NSURL URLWithString:realURL]]) + NSURL *realURL = [text attribute:NSLinkAttributeName atIndex:matchRange.location effectiveRange:nil]; + NSString *realURLString = realURL == nil ? [plainText substringWithRange:matchRange] : [realURL absoluteString]; + + if (![self ignoreMatch:realURLString] && realURL != nil && ![self shouldIgnoreURL:realURL]) { if ([match resultType] == NSTextCheckingTypeLink) { From d3fbacc8b2b565ef68c252929db79411d2713190 Mon Sep 17 00:00:00 2001 From: "Carlos Oliva (MBA)" Date: Wed, 22 Jun 2016 02:26:48 -0400 Subject: [PATCH 4/4] More NSLinkAttributeName handling --- KILabel/Source/KILabel.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/KILabel/Source/KILabel.m b/KILabel/Source/KILabel.m index 0f8a151..7f72c53 100644 --- a/KILabel/Source/KILabel.m +++ b/KILabel/Source/KILabel.m @@ -704,7 +704,14 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event if (touchedLink) { NSRange range = [[touchedLink objectForKey:KILabelRangeKey] rangeValue]; - NSString *touchedSubstring = [touchedLink objectForKey:KILabelLinkKey]; + id touchedLinkObject = [touchedLink objectForKey:KILabelLinkKey]; + NSString *touchedSubstring; + if([touchedLinkObject isKindOfClass:[NSURL class]]) { + touchedSubstring = [(NSURL *)touchedLinkObject absoluteString]; + } else { + touchedSubstring = touchedLinkObject; + } + KILinkType linkType = (KILinkType)[[touchedLink objectForKey:KILabelLinkTypeKey] intValue]; [self receivedActionForLinkType:linkType string:touchedSubstring range:range];