UITextView带有可点击链接但没有文字突出显示

Tre*_*s W 24 objective-c highlight uitextview ios ios7

我有一个显示不可编辑文本的UITextView.我希望文本能够自动解析用户的链接,电话号码等,以及可点击的文本.

我不希望用户能够突出显示文本,因为我想要覆盖那些长按和双击交互以执行不同的操作.

为了在iOS7中解析链接,需要为UITextView打开Selectable开关,但Selectable也可以启用突出显示,这是我不想要的.

我尝试覆盖LongPress手势以防止突出显示,但这似乎也禁用了链接上的普通水龙头......

for (UIGestureRecognizer *recognizer in cell.messageTextView.gestureRecognizers) {
    if ([recognizer isKindOfClass:[UILongPressGestureRecognizer class]]){
        recognizer.enabled = NO;
    }
    if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]){
        recognizer.enabled = YES;
    }
}
Run Code Online (Sandbox Code Playgroud)

有很多类似的线程,但似乎没有解决这个特定的链接启用问题,文本不突出显示.

小智 24

我正在处理完全相同的问题,我能做的最好的事情就是通过将以下内容添加到UITextView的委托来立即清除选择:

- (void)textViewDidChangeSelection:(UITextView *)textView {
    if(!NSEqualRanges(textView.selectedRange, NSMakeRange(0, 0))) {
        textView.selectedRange = NSMakeRange(0, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意检查以防止递归.这几乎解决了这个问题,因为只有选择被禁用 - 链接仍然有用.

另一个切线问题是文本视图仍然会成为第一响应者,您可以通过在设置所选范围后设置所需的第一响应者来解决此问题.

注意:剩下的唯一视觉怪异是按住并放大放大镜.


lra*_*135 17

我不确定这是否适用于您的特定情况,但我有一个类似的情况,我需要textview链接可点击但不希望文本选择发生,我使用textview在CollectionViewCell中显示数据.

我只需要覆盖-canBecomeFirstResponder并返回NO.

@interface MYTextView : UITextView
@end

@implementation MYTextView

- (BOOL)canBecomeFirstResponder {
    return NO;
}

@end
Run Code Online (Sandbox Code Playgroud)

  • 在iOS 9.2上似乎不适合我 (3认同)
  • 而且没有放大镜故障!这是一个更好的答案. (2认同)
  • iOS 10.3.1 模拟器对我不起作用(注意,我的文本视图不可编辑)。该方法被调用,但文本选择仍然发生。 (2认同)

Jak*_*par 11

正如我在另一篇文章中所写,还有另一种解决方案.

经过几次测试,我找到了解决方案.

如果您希望链接处于活动状态且未启用选择,则需要编辑gestureRecognizers.

例如 - 有3个LongPressGestureRecognizers.一个用于单击链接(minimumPressDuration = 0.12),第二个用于放大可编辑模式(minimumPressDuration = 0.5),第三个用于选择(minimumPressDuration = 0.8).此解决方案删除LongPressGestureRecognizer以进行选择,其次用于缩放编辑模式.

NSArray *textViewGestureRecognizers = self.captionTextView.gestureRecognizers;
NSMutableArray *mutableArrayOfGestureRecognizers = [[NSMutableArray alloc] init];
for (UIGestureRecognizer *gestureRecognizer in textViewGestureRecognizers) {
    if (![gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
        [mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
    } else {
        UILongPressGestureRecognizer *longPressGestureRecognizer = (UILongPressGestureRecognizer *)gestureRecognizer;
        if (longPressGestureRecognizer.minimumPressDuration < 0.3) {
            [mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
        }
    }
}
self.captionTextView.gestureRecognizers = mutableArrayOfGestureRecognizers;
Run Code Online (Sandbox Code Playgroud)

在iOS 9上测试过,但它应该适用于所有版本(iOS 7,8,9).我希望它有所帮助!:)

  • 可能不是最终解决方案,因为它可以打破未来版本,但现在是唯一真正有效的解决方案.大! (2认同)

Vat*_*kla 5

Swift 4,Xcode 9.2

下面是一些不同的方法,

class TextView: UITextView {
    //MARK: Properties    
    open var didTouchedLink:((URL,NSRange,CGPoint) -> Void)?

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    }

    open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = Array(touches)[0]
        if let view = touch.view {
            let point = touch.location(in: view)
            self.tapped(on: point)
        }
    }
}

extension TextView {
    fileprivate func tapped(on point:CGPoint) {
        var location: CGPoint = point
        location.x -= self.textContainerInset.left
        location.y -= self.textContainerInset.top
        let charIndex = layoutManager.characterIndex(for: location, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
        guard charIndex < self.textStorage.length else {
            return
        }
        var range = NSRange(location: 0, length: 0)
        if let attributedText = self.attributedText {
            if let link = attributedText.attribute(NSAttributedStringKey.link, at: charIndex, effectiveRange: &range) as? URL {
                print("\n\t##-->You just tapped on '\(link)' withRange = \(NSStringFromRange(range))\n")
                self.didTouchedLink?(link, range, location)
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用,

let textView = TextView()//Init your textview and assign attributedString and other properties you want.
textView.didTouchedLink = { (url,tapRange,point) in
//here goes your other logic for successfull URL location
}
Run Code Online (Sandbox Code Playgroud)