{"action":"created","issue":{"url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/5","labels_url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/5/comments","events_url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/5/events","html_url":"https://github.com/zacwest/ZSWTappableLabel/issues/5","id":94870198,"number":5,"title":"Tapping on link propagates link style to whole attributed string","user":{"login":"mergesort","id":716513,"avatar_url":"https://avatars.githubusercontent.com/u/716513?v=3","gravatar_id":"","url":"https://api.github.com/users/mergesort","html_url":"https://github.com/mergesort","followers_url":"https://api.github.com/users/mergesort/followers","following_url":"https://api.github.com/users/mergesort/following{/other_user}","gists_url":"https://api.github.com/users/mergesort/gists{/gist_id}","starred_url":"https://api.github.com/users/mergesort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mergesort/subscriptions","organizations_url":"https://api.github.com/users/mergesort/orgs","repos_url":"https://api.github.com/users/mergesort/repos","events_url":"https://api.github.com/users/mergesort/events{/privacy}","received_events_url":"https://api.github.com/users/mergesort/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/labels/needs-investigation","name":"needs-investigation","color":"5319e7"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-07-14T05:20:07Z","updated_at":"2015-07-14T19:58:54Z","closed_at":"2015-07-14T19:04:04Z","body":"I'm having an issue where I tap on a link, and it takes a string that was bolded only on the `a` attribute, and makes the entire label bold, and can't quite track it down.\r\n\r\nI've subclassed `ZSWTappableLabel` so I can create methods that take in a string and convert it to an attributed string with my own custom attributes.\r\n\r\nThe results look like this.\r\n\r\n**This is before I tapped on it. `@victoriasj` is bold because it is the link, and `visited` is not bold, because it is not part of the link.**\r\n![](https://cloud.githubusercontent.com/assets/716513/8666892/b55fecc8-29c5-11e5-8a01-a0cf0e0a9038.png)\r\n\r\n**This is after I tapped on it. (In this case I tapped on each label to demonstrate what happens, not tapping on one influencing the other cells). Note that `@victoriasj` is bold as it should be, but `visited` is as well, which it shouldn't be.**\r\n\r\n![After tapping (on each label individually in this case)](https://cloud.githubusercontent.com/assets/716513/8666895/bb81b3f2-29c5-11e5-93ab-f3f64a48c1f3.png)\r\n\r\n\r\nThe relevant parts of the subclass looks like this:\r\n\r\n```\r\n- (void)setDataDetectingText:(NSString *)text linkColor:(UIColor *)color highlightedColor:(UIColor *)highlightedColor linkFont:(UIFont *)font\r\n{\r\n    self.userInteractionEnabled = YES;\r\n\r\n    NSString *htmlText = [self anchorTaggedString:text withDataDetectors:DataDetectorTypeAll];\r\n\r\n    ZSWTaggedStringOptions *options = [ZSWTaggedStringOptions options];\r\n    [options setDynamicAttributes:^NSDictionary *(NSString *tagName, NSDictionary *tagAttributes, NSDictionary *existingStringAttributes) {\r\n        NSString *href = tagAttributes[@\"href\"];\r\n        NSURL *URL = href.length > 0 ? [NSURL URLWithString:href] : nil;\r\n\r\n        if (!URL)\r\n        {\r\n            return nil;\r\n        }\r\n        else\r\n        {\r\n            return @{\r\n                        ZSWTappableLabelTappableRegionAttributeName : @YES,\r\n                        NSUnderlineStyleAttributeName : @(NSUnderlineStyleNone),\r\n                        ZSWTappableLabelHighlightedBackgroundAttributeName : [UIColor clearColor],\r\n                        ZSWTappableLabelHighlightedForegroundAttributeName : highlightedColor,\r\n                        NSForegroundColorAttributeName : color,\r\n                        NSFontAttributeName : font,\r\n                        URLMetadataKey : URL\r\n                    };\r\n\r\n        }\r\n    } forTagName:@\"a\"];\r\n\r\n    self.attributedText = [[ZSWTaggedString stringWithString:htmlText] attributedStringWithOptions:options];\r\n}\r\n\r\n- (void)setDataDetectingText:(NSString *)text\r\n{\r\n    [self setDataDetectingText:text linkColor:self.textColor highlightedColor:[UIColor lightGrayColor] linkFont:[UIFont boldSystemFontOfSize:self.font.pointSize]];\r\n}\r\n\r\n\r\n////////////////////////////////////////////////////////////////////////////////\r\n#pragma mark - Delegation - ZSWTappableLabelDelegate\r\n\r\n- (void)tappableLabel:(ZSWTappableLabel *)tappableLabel tappedAtIndex:(NSInteger)idx withAttributes:(NSDictionary *)attributes\r\n{\r\n    NSURL *URL = attributes[URLMetadataKey];\r\n    \r\n    if ([UsernameMetadataDetector URLContainsMetadata:URL])\r\n    {\r\n        if (self.tappedMetadata)\r\n        {\r\n            self.tappedMetadata([UsernameMetadataDetector metadataFromURL:URL]);\r\n        }\r\n    }\r\n    else if ([[UIApplication sharedApplication] canOpenURL:URL])\r\n    {\r\n        [[UIApplication sharedApplication] openURL:URL];\r\n    }\r\n}\r\n\r\n\r\n////////////////////////////////////////////////////////////////////////////////\r\n#pragma mark - Private\r\n\r\n- (NSString *)anchorTaggedString:(NSString *)string withDataDetectors:(DataDetectorType)type\r\n{\r\n    NSString *htmlText = nil;\r\n\r\n    if (string.length > 0)\r\n    {\r\n        NSString * (^anchorForUsername) (NSString *) = ^(NSString *string){\r\n            NSString *template = nil;\r\n            template = [NSString stringWithFormat:@\"<a href=\\\"%@\\\">%@</a>\", [UsernameMetadataDetector URLStringFromMetadataString:@\"$0\"], [UsernameMetadataDetector unprefixedUsernameString:@\"$0\"]];\r\n            NSRegularExpression *regex = [UsernameMetadataDetector usernameRegularExpression];\r\n            NSString *replacedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, string.length) withTemplate:template];\r\n            return replacedString;\r\n        };\r\n\r\n        if (type == DataDetectorTypeAll)\r\n        {\r\n            htmlText = anchorForUsername(string);\r\n            htmlText = anchorForList(string);\r\n        }\r\n        else if (type == DataDetectorTypeUsername)\r\n        {\r\n            htmlText = anchorForUsername(string);\r\n        }\r\n    }\r\n\r\n    return htmlText;\r\n}\r\n```\r\n\r\nOther things to note: Even if I disable the tapDelegate (which is self), the issue still occurs.\r\n\r\nThanks a lot for the great work! This issue aside, using ZSWTappableLabel has been terrific."},"comment":{"url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/comments/121363916","html_url":"https://github.com/zacwest/ZSWTappableLabel/issues/5#issuecomment-121363916","issue_url":"https://api.github.com/repos/zacwest/ZSWTappableLabel/issues/5","id":121363916,"user":{"login":"zacwest","id":74188,"avatar_url":"https://avatars.githubusercontent.com/u/74188?v=3","gravatar_id":"","url":"https://api.github.com/users/zacwest","html_url":"https://github.com/zacwest","followers_url":"https://api.github.com/users/zacwest/followers","following_url":"https://api.github.com/users/zacwest/following{/other_user}","gists_url":"https://api.github.com/users/zacwest/gists{/gist_id}","starred_url":"https://api.github.com/users/zacwest/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zacwest/subscriptions","organizations_url":"https://api.github.com/users/zacwest/orgs","repos_url":"https://api.github.com/users/zacwest/repos","events_url":"https://api.github.com/users/zacwest/events{/privacy}","received_events_url":"https://api.github.com/users/zacwest/received_events","type":"User","site_admin":false},"created_at":"2015-07-14T19:58:54Z","updated_at":"2015-07-14T19:58:54Z","body":"In your example, could you print out what the `[super font]` value is before and after doing `-setAttributedText:` on the label? \r\n\r\nYou're running into, I think, UILabel being weird about how it sets `self.font` - I believe it behaves like so:\r\n\r\n1. Font is `normal`\r\n2. String is set, where unknown values are filled with `normal`\r\n3. Font is updated to new string, first index is `bold`\r\n4. ZSWTappableLabel saves the string, filling in blanks with `bold`\r\n\r\nVisually, until ZSWTappableLabel executes, it's using the value saved in (2), but when the label goes to update due to highlight changes, it's using the value saved in (4).\r\n\r\nI think this is a bug in this class, but it's pretty nuanced. I can picture a few solutions:\r\n\r\n1. We re-apply the string from (4) so it's obvious what's happening.\r\n2. We throw an exception if any parts of the string lack fonts, or at least log to console.\r\n3. We grab the font before setting super, so (4) matches (2). Note that `self.font` would be \"wrong\" still, since UILabel is using idx0 after setting. \r\n4. We grab the font before setting super, and re-apply it after (4).\r\n\r\nI'll have to think about this some more, but I'm glad you were able to figure it out."}}