Przeglądaj źródła

add tap and long press action for YYLabel

ibireme 9 lat temu
rodzic
commit
947db8fa1e
3 zmienionych plików z 59 dodań i 14 usunięć
  1. 0 1
      Demo/YYTextDemo/YYTextAttributeExample.m
  2. 12 0
      YYText/YYLabel.h
  3. 47 13
      YYText/YYLabel.m

+ 0 - 1
Demo/YYTextDemo/YYTextAttributeExample.m

@@ -124,7 +124,6 @@
     {
         NSMutableAttributedString *one = [[NSMutableAttributedString alloc] initWithString:@"Link"];
         one.yy_font = [UIFont boldSystemFontOfSize:30];
-        one.yy_underlineColor = one.yy_color;
         one.yy_underlineStyle = NSUnderlineStyleSingle;
         
         /// 1. you can set a highlight with these code

+ 12 - 0
YYText/YYLabel.h

@@ -208,6 +208,18 @@
 /// @name Interacting with Text Data
 ///=============================================================================
 
+/**
+ When user tap the label, this action will be called (similar to tap gesture).
+ The default value is nil.
+ */
+@property (nullable, nonatomic, copy) YYTextAction textTapAction;
+
+/**
+ When user long press the label, this action will be called (similar to long press gesture).
+ The default value is nil.
+ */
+@property (nullable, nonatomic, copy) YYTextAction textLongPressAction;
+
 /**
  When user tap the highlight range of text, this action will be called.
  The default value is nil.

+ 47 - 13
YYText/YYLabel.m

@@ -64,6 +64,9 @@ static dispatch_queue_t YYLabelGetReleaseQueue() {
         unsigned int swallowTouch : 1;
         unsigned int touchMoved : 1;
         
+        unsigned int hasTapAction : 1;
+        unsigned int hasLongPressAction : 1;
+        
         unsigned int contentsNeedFade : 1;
     } _state;
 }
@@ -154,6 +157,19 @@ static dispatch_queue_t YYLabelGetReleaseQueue() {
 
 - (void)_trackDidLongPress {
     [self _endLongPressTimer];
+    if (_state.hasLongPressAction && _textLongPressAction) {
+        NSRange range = NSMakeRange(NSNotFound, 0);
+        CGRect rect = CGRectNull;
+        CGPoint point = [self _convertPointToLayout:_touchBeganPoint];
+        YYTextRange *textRange = [self._innerLayout textRangeAtPoint:point];
+        CGRect textRect = [self._innerLayout rectForRange:textRange];
+        textRect = [self _convertRectFromLayout:textRect];
+        if (textRange) {
+            range = textRange.asRange;
+            rect = textRect;
+        }
+        _textLongPressAction(self, _innerText, range, rect);
+    }
     if (_highlight) {
         YYTextAction longPressAction = _highlight.longPressAction ? _highlight.longPressAction : _highlightLongPressAction;
         if (longPressAction) {
@@ -526,14 +542,16 @@ static dispatch_queue_t YYLabelGetReleaseQueue() {
     _highlight = [self _getHighlightAtPoint:point range:&_highlightRange];
     _highlightLayout = nil;
     _shrinkHighlightLayout = nil;
+    _state.hasTapAction = _textTapAction != nil;
+    _state.hasLongPressAction = _textLongPressAction != nil;
     
-    if (_highlight) {
+    if (_highlight || _textTapAction || _textLongPressAction) {
         _touchBeganPoint = point;
         _state.trackingTouch = YES;
         _state.swallowTouch = YES;
         _state.touchMoved = NO;
         [self _startLongPressTimer];
-        [self _showHighlightAnimated:NO];
+        if (_highlight) [self _showHighlightAnimated:NO];
     } else {
         _state.trackingTouch = NO;
         _state.swallowTouch = NO;
@@ -563,7 +581,7 @@ static dispatch_queue_t YYLabelGetReleaseQueue() {
                 [self _endLongPressTimer];
             }
         }
-        if (_state.touchMoved) {
+        if (_state.touchMoved && _highlight) {
             YYTextHighlight *highlight = [self _getHighlightAtPoint:point range:NULL];
             if (highlight == _highlight) {
                 [self _showHighlightAnimated:_fadeOnHighlight];
@@ -584,18 +602,34 @@ static dispatch_queue_t YYLabelGetReleaseQueue() {
     
     if (_state.trackingTouch) {
         [self _endLongPressTimer];
-        if (!_state.touchMoved || [self _getHighlightAtPoint:point range:NULL] == _highlight) {
-            YYTextAction tapAction = _highlight.tapAction ? _highlight.tapAction : _highlightTapAction;
-            if (tapAction) {
-                YYTextPosition *start = [YYTextPosition positionWithOffset:_highlightRange.location];
-                YYTextPosition *end = [YYTextPosition positionWithOffset:_highlightRange.location + _highlightRange.length affinity:YYTextAffinityBackward];
-                YYTextRange *range = [YYTextRange rangeWithStart:start end:end];
-                CGRect rect = [self._innerLayout rectForRange:range];
-                rect = [self _convertRectFromLayout:rect];
-                tapAction(self, _innerText, _highlightRange, rect);
+        if (!_state.touchMoved && _textTapAction) {
+            NSRange range = NSMakeRange(NSNotFound, 0);
+            CGRect rect = CGRectNull;
+            CGPoint point = [self _convertPointToLayout:_touchBeganPoint];
+            YYTextRange *textRange = [self._innerLayout textRangeAtPoint:point];
+            CGRect textRect = [self._innerLayout rectForRange:textRange];
+            textRect = [self _convertRectFromLayout:textRect];
+            if (textRange) {
+                range = textRange.asRange;
+                rect = textRect;
+            }
+            _textTapAction(self, _innerText, range, rect);
+        }
+        
+        if (_highlight) {
+            if (!_state.touchMoved || [self _getHighlightAtPoint:point range:NULL] == _highlight) {
+                YYTextAction tapAction = _highlight.tapAction ? _highlight.tapAction : _highlightTapAction;
+                if (tapAction) {
+                    YYTextPosition *start = [YYTextPosition positionWithOffset:_highlightRange.location];
+                    YYTextPosition *end = [YYTextPosition positionWithOffset:_highlightRange.location + _highlightRange.length affinity:YYTextAffinityBackward];
+                    YYTextRange *range = [YYTextRange rangeWithStart:start end:end];
+                    CGRect rect = [self._innerLayout rectForRange:range];
+                    rect = [self _convertRectFromLayout:rect];
+                    tapAction(self, _innerText, _highlightRange, rect);
+                }
             }
+            [self _removeHighlightAnimated:_fadeOnHighlight];
         }
-        [self _removeHighlightAnimated:_fadeOnHighlight];
     }
     
     if (!_state.swallowTouch) {