diff --git a/AttributedLabel Example/AttributedLabel Example.xcodeproj/project.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout b/AttributedLabel Example/AttributedLabel Example.xcodeproj/project.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout
new file mode 100644
index 0000000..1c3dadd
--- /dev/null
+++ b/AttributedLabel Example/AttributedLabel Example.xcodeproj/project.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout
@@ -0,0 +1,41 @@
+
+
+
+
+ IDESourceControlProjectFavoriteDictionaryKey
+
+ IDESourceControlProjectIdentifier
+ 8E00B687-E064-4809-8B28-8796809624B8
+ IDESourceControlProjectName
+ AttributedLabel Example
+ IDESourceControlProjectOriginsDictionary
+
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ https://github.com/JonasGessner/OHAttributedLabel.git
+
+ IDESourceControlProjectPath
+ AttributedLabel Example/AttributedLabel Example.xcodeproj/project.xcworkspace
+ IDESourceControlProjectRelativeInstallPathDictionary
+
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ ../../..
+
+ IDESourceControlProjectURL
+ https://github.com/JonasGessner/OHAttributedLabel.git
+ IDESourceControlProjectVersion
+ 110
+ IDESourceControlProjectWCCIdentifier
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ IDESourceControlProjectWCConfigurations
+
+
+ IDESourceControlRepositoryExtensionIdentifierKey
+ public.vcs.git
+ IDESourceControlWCCIdentifierKey
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ IDESourceControlWCCName
+ OHAttributedLabel
+
+
+
+
diff --git a/AttributedLabel Example/AttributedLabel Example.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout b/AttributedLabel Example/AttributedLabel Example.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout
new file mode 100644
index 0000000..f033151
--- /dev/null
+++ b/AttributedLabel Example/AttributedLabel Example.xcworkspace/xcshareddata/AttributedLabel Example.xccheckout
@@ -0,0 +1,41 @@
+
+
+
+
+ IDESourceControlProjectFavoriteDictionaryKey
+
+ IDESourceControlProjectIdentifier
+ 183D72E1-D028-4B77-8A12-AC9BBB43440E
+ IDESourceControlProjectName
+ AttributedLabel Example
+ IDESourceControlProjectOriginsDictionary
+
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ https://github.com/JonasGessner/OHAttributedLabel.git
+
+ IDESourceControlProjectPath
+ AttributedLabel Example/AttributedLabel Example.xcworkspace
+ IDESourceControlProjectRelativeInstallPathDictionary
+
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ ../..
+
+ IDESourceControlProjectURL
+ https://github.com/JonasGessner/OHAttributedLabel.git
+ IDESourceControlProjectVersion
+ 110
+ IDESourceControlProjectWCCIdentifier
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ IDESourceControlProjectWCConfigurations
+
+
+ IDESourceControlRepositoryExtensionIdentifierKey
+ public.vcs.git
+ IDESourceControlWCCIdentifierKey
+ C1454787-2CDA-4B38-A9B3-B2369AB9C48B
+ IDESourceControlWCCName
+ OHAttributedLabel
+
+
+
+
diff --git a/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.m b/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.m
index f6962dd..a1b5cca 100644
--- a/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.m
+++ b/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.m
@@ -175,6 +175,10 @@ -(UIColor*)attributedLabel:(OHAttributedLabel*)attrLabel colorForLink:(NSTextChe
}
}
+- (void)attributedLabel:(OHAttributedLabel *)attributedLabel longPressedLink:(NSTextCheckingResult *)linkInfo {
+ NSLog(@"Long Pressed Link %@", linkInfo);
+}
+
-(BOOL)attributedLabel:(OHAttributedLabel *)attributedLabel shouldFollowLink:(NSTextCheckingResult *)linkInfo
{
[self.visitedLinks addObject:objectForLinkInfo(linkInfo)];
diff --git a/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m b/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
index 0e896a9..ddebe67 100644
--- a/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
+++ b/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
@@ -178,6 +178,9 @@ -(IBAction)changeLineSpacing:(UISlider*)slider
#pragma mark - OHAttributedString Delegate Method
/////////////////////////////////////////////////////////////////////////////
+- (void)attributedLabel:(OHAttributedLabel *)attributedLabel longPressedLink:(NSTextCheckingResult *)linkInfo {
+ NSLog(@"Long Pressed Link %@", linkInfo);
+}
-(BOOL)attributedLabel:(OHAttributedLabel *)attributedLabel shouldFollowLink:(NSTextCheckingResult *)linkInfo
{
diff --git a/AttributedLabel Example/Classes/TableViewDemo/TableViewDemoViewController.m b/AttributedLabel Example/Classes/TableViewDemo/TableViewDemoViewController.m
index 3742d5f..ee4827c 100644
--- a/AttributedLabel Example/Classes/TableViewDemo/TableViewDemoViewController.m
+++ b/AttributedLabel Example/Classes/TableViewDemo/TableViewDemoViewController.m
@@ -141,6 +141,10 @@ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *
#pragma mark - OHAttributedLabel Delegate Method
/////////////////////////////////////////////////////////////////////////////
+- (void)attributedLabel:(OHAttributedLabel *)attributedLabel longPressedLink:(NSTextCheckingResult *)linkInfo {
+ NSLog(@"Long Pressed Link %@", linkInfo);
+}
+
-(BOOL)attributedLabel:(OHAttributedLabel *)attributedLabel shouldFollowLink:(NSTextCheckingResult *)linkInfo
{
if ([[UIApplication sharedApplication] canOpenURL:linkInfo.extendedURL])
diff --git a/OHAttributedLabel/Source/NSAttributedString+Attributes.m b/OHAttributedLabel/Source/NSAttributedString+Attributes.m
index e64f962..6f0be76 100644
--- a/OHAttributedLabel/Source/NSAttributedString+Attributes.m
+++ b/OHAttributedLabel/Source/NSAttributedString+Attributes.m
@@ -73,7 +73,7 @@ -(CGSize)sizeConstrainedToSize:(CGSize)maxSize fitRange:(NSRange*)fitRange
sz = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,CFRangeMake(0,0),NULL,maxSize,&fitCFRange);
sz = CGSizeMake( floorf(sz.width+1) , floorf(sz.height+1) ); // take 1pt of margin for security
CFRelease(framesetter);
-
+
if (fitRange)
{
*fitRange = NSMakeRange((NSUInteger)fitCFRange.location, (NSUInteger)fitCFRange.length);
@@ -194,7 +194,7 @@ -(void)setFontFamily:(NSString*)fontFamily size:(CGFloat)size bold:(BOOL)isBold
CTFontRef aFont = CTFontCreateWithFontDescriptor(desc, size, NULL);
CFRelease(desc);
if (!aFont) return;
-
+
[self removeAttribute:(__bridge NSString*)kCTFontAttributeName range:range]; // Work around for Apple leak
[self addAttribute:(__bridge NSString*)kCTFontAttributeName value:(__bridge id)aFont range:range];
CFRelease(aFont);
@@ -236,11 +236,15 @@ -(void)changeFontWithTraits:(CTFontSymbolicTraits)traits
[self beginEditing];
do {
// Get font at startPoint
+ BOOL hadCurrentFont = YES;
+
CTFontRef currentFont = (__bridge CTFontRef)[self attribute:(__bridge NSString*)kCTFontAttributeName atIndex:startPoint effectiveRange:&effectiveRange];
- if (!currentFont)
- {
+
+ if (!currentFont) {
+ hadCurrentFont = NO;
currentFont = CTFontCreateUIFontForLanguage(kCTFontLabelFontType, 0.0, NULL);
}
+
// The range for which this font is effective
NSRange fontRange = NSIntersectionRange(range, effectiveRange);
// Create the font variant for this font according to new traits
@@ -272,9 +276,12 @@ -(void)changeFontWithTraits:(CTFontSymbolicTraits)traits
if (fontNameRef) CFRelease(fontNameRef);
}
+ if (!hadCurrentFont) {
+ CFRelease(currentFont);
+ }
+
// Apply the new font with new traits
- if (newFont)
- {
+ if (newFont) {
[self removeAttribute:(__bridge NSString*)kCTFontAttributeName range:fontRange]; // Work around for Apple leak
[self addAttribute:(__bridge NSString*)kCTFontAttributeName value:(__bridge id)newFont range:fontRange];
CFRelease(newFont);
@@ -296,18 +303,18 @@ -(void)setTextBold:(BOOL)isBold range:(NSRange)range
[self changeFontWithTraits:(isBold?kCTFontTraitBold:0)
mask:kCTFontTraitBold
range:range newFontFinder:^NSString *(NSString *currentFontName)
- {
- if ([currentFontName isEqualToString:kHelveticaNeueUI_Italic] || [currentFontName isEqualToString:kHelveticaNeueUI_Bold_Italic])
- {
- // Italic private font
- return isBold ? kHelveticaNeueUI_Bold_Italic : kHelveticaNeueUI_Italic;
- } else if ([currentFontName isEqualToString:kHelveticaNeueUI] || [currentFontName isEqualToString:kHelveticaNeueUI_Bold]) {
- // Non-Italic private font
- return isBold ? kHelveticaNeueUI_Bold : kHelveticaNeueUI;
- } else {
- return nil;
- }
- }];
+ {
+ if ([currentFontName isEqualToString:kHelveticaNeueUI_Italic] || [currentFontName isEqualToString:kHelveticaNeueUI_Bold_Italic])
+ {
+ // Italic private font
+ return isBold ? kHelveticaNeueUI_Bold_Italic : kHelveticaNeueUI_Italic;
+ } else if ([currentFontName isEqualToString:kHelveticaNeueUI] || [currentFontName isEqualToString:kHelveticaNeueUI_Bold]) {
+ // Non-Italic private font
+ return isBold ? kHelveticaNeueUI_Bold : kHelveticaNeueUI;
+ } else {
+ return nil;
+ }
+ }];
}
-(void)setTextItalics:(BOOL)isItalics range:(NSRange)range
@@ -366,9 +373,9 @@ -(void)modifyParagraphStylesInRange:(NSRange)range withBlock:(void(^)(OHParagrap
while (NSLocationInRange(loc, range))
{
CTParagraphStyleRef currentCTStyle = (__bridge CTParagraphStyleRef)[self attribute:(__bridge NSString*)kCTParagraphStyleAttributeName
- atIndex:loc longestEffectiveRange:rangePtr inRange:range];
+ atIndex:loc longestEffectiveRange:rangePtr inRange:range];
__block OHParagraphStyle* paraStyle = [OHParagraphStyle paragraphStyleWithCTParagraphStyle:currentCTStyle];
- block(paraStyle);
+ block(paraStyle);
[self setParagraphStyle:paraStyle range:*rangePtr];
loc = NSMaxRange(*rangePtr);
diff --git a/OHAttributedLabel/Source/OHAttributedLabel.h b/OHAttributedLabel/Source/OHAttributedLabel.h
index 7d43241..f16a3e7 100755
--- a/OHAttributedLabel/Source/OHAttributedLabel.h
+++ b/OHAttributedLabel/Source/OHAttributedLabel.h
@@ -39,6 +39,9 @@
@protocol OHAttributedLabelDelegate
@optional
-(BOOL)attributedLabel:(OHAttributedLabel*)attributedLabel shouldFollowLink:(NSTextCheckingResult*)linkInfo;
+
+-(void)attributedLabel:(OHAttributedLabel*)attributedLabel longPressedLink:(NSTextCheckingResult*)linkInfo;
+
//! @parameter underlineStyle Combination of CTUnderlineStyle and CTUnderlineStyleModifiers
-(UIColor*)attributedLabel:(OHAttributedLabel*)attributedLabel colorForLink:(NSTextCheckingResult*)linkInfo underlineStyle:(int32_t*)underlineStyle;
@end
diff --git a/OHAttributedLabel/Source/OHAttributedLabel.m b/OHAttributedLabel/Source/OHAttributedLabel.m
index 7053881..ee65ebe 100755
--- a/OHAttributedLabel/Source/OHAttributedLabel.m
+++ b/OHAttributedLabel/Source/OHAttributedLabel.m
@@ -60,6 +60,7 @@ @interface OHAttributedLabel(/* Private */)
NSMutableArray* _customLinks;
CGPoint _touchStartPoint;
UIGestureRecognizer *_gestureRecogniser;
+ UIGestureRecognizer *_longTapGestureReconizer;
}
@property(nonatomic, retain) NSTextCheckingResult* activeLink;
-(NSTextCheckingResult*)linkAtCharacterIndex:(CFIndex)idx;
@@ -146,6 +147,10 @@ - (void)commonInit
_gestureRecogniser = [[OHTouchesGestureRecognizer alloc] initWithTarget:self action:@selector(_gestureRecognised:)];
_gestureRecogniser.delegate = self;
[self addGestureRecognizer:_gestureRecogniser];
+
+ _longTapGestureReconizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
+ _longTapGestureReconizer.delegate = self;
+ [self addGestureRecognizer:_longTapGestureReconizer];
}
- (id) initWithFrame:(CGRect)aFrame
@@ -442,6 +447,23 @@ -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
return hitResult;
}
+- (void)longPress:(UILongPressGestureRecognizer *)gesture {
+ CGPoint pt = [gesture locationInView:self];
+
+ if (gesture.state == UIGestureRecognizerStateBegan) {
+ // Check that the link on touchEnd is the same as the link on touchBegan
+ NSTextCheckingResult* linkAtTouchesEnded = [self linkAtPoint:pt];
+ BOOL closeToStart = (fabs(_touchStartPoint.x - pt.x) < 10 && fabs(_touchStartPoint.y - pt.y) < 10);
+
+ // we must check on equality of the ranges themselves since the data detectors create new results
+ if (_activeLink && (NSEqualRanges(_activeLink.range,linkAtTouchesEnded.range) || closeToStart)) {
+ // Same link on touchEnded than the one on touchBegan, so trigger it
+ [self processLongPressActiveLink];
+ }
+ }
+
+}
+
-(void)_gestureRecognised:(UIGestureRecognizer*)recogniser
{
CGPoint pt = [recogniser locationInView:self];
@@ -491,6 +513,14 @@ -(void)_gestureRecognised:(UIGestureRecognizer*)recogniser
}
}
+- (void)processLongPressActiveLink {
+ NSTextCheckingResult* linkToOpen = _activeLink;
+
+ if ([self.delegate respondsToSelector:@selector(attributedLabel:longPressedLink:)]) {
+ [self.delegate attributedLabel:self longPressedLink:linkToOpen];
+ }
+}
+
- (void)processActiveLink
{
NSTextCheckingResult* linkToOpen = _activeLink;
@@ -677,7 +707,7 @@ - (CGSize)sizeThatFits:(CGSize)size
/////////////////////////////////////////////////////////////////////////////////////
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
- return ([[otherGestureRecognizer.view class] isSubclassOfClass:[UIScrollView class]]);
+ return (otherGestureRecognizer == _longTapGestureReconizer || otherGestureRecognizer == _gestureRecogniser || [[otherGestureRecognizer.view class] isSubclassOfClass:[UIScrollView class]]);
}