在 UITextView 中更改一个 link 的属性
Change attributes of one link in UITextView
我有一个带有多个 URL 的 UITextView
,我通过将 dataDetectorTypes
属性 设置为 UIDataDetectorTypeLink
来激活它们。然后我使用 linkTextAttributes
属性 来设置 link 的颜色。现在,当用户点击 link 之一(使用 UITapGestureRecognizer
)时,我只想更改 link 的颜色。如果我改变 linkTextAttributes
,所有 link 都会改变颜色。
我怎样才能只改变被点击的 link 的颜色?
如果这些网址是固定的。
例如:
我有以下网址:
我会将它们放入 NSAttributedString
使用 NSMutableAttributedString 将它们全部组合起来
NSMutableAttributedString *urlsAttributedText = [[NSMutableAttributedString alloc]init];
NSAttributedString *url1 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.123.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
NSAttributedString *url2 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.456.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor greenColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
NSAttributedString *url3 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.789.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor redColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
[urlsAttributedText url1];
[urlsAttributedText appendAttributedString:url2];
[urlsAttributedText appendAttributedString:url3];
self.texView.attributedText = urlsAttributedText;
干杯!
我想我解决了它,使用名为 UITextView
的子类,它有一个 rangeOfLink
属性.
首先,在我的 UIViewController
viewDidLoad:
中,我添加
self.textView.dataDetectorTypes = UIDataDetectorTypeLink; // change for other link types
self.textView.selectable = YES;
self.textView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(handleTap:)];
tapGesture.cancelsTouchesInView = YES;
[self.textView addGestureRecognizer: tapGesture];
[self.textView setNeedsDisplay]; // force a redraw so that drawRect is called
然后在 handleTap
中,我这样做:
MyTextViewWithLink *aTextView = (IDTextViewWithLink *) recognizer.view;
if (aTextView != self.textView)
return;
if (recognizer.state == UIGestureRecognizerStateEnded)
{
CGPoint location = [recognizer locationInView: aTextView];
// this returns an NSTextCheckingResult if location is inside a link
NSTextCheckingResult *result = [self textCheckingResultAtPoint: location inTextView: aTextView];
if (result)
{
aTextView.rangeOfLink = result.range;
[aTextView setNeedsDisplay]; // this will force the color change
// open url
}
}
最后我在我的 UITextView
子类中覆盖了 drawRect
:
self.linkTextAttributes = [NSDictionary dictionary];
NSError *error = nil;
NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error: &error]; // change for other link types
if (!error && dataDetector)
{
NSArray* resultString = [dataDetector matchesInString: self.text
options: NSMatchingReportProgress
range: NSMakeRange(0, [self.text length])];
if (resultString.count > 0)
{
NSMutableAttributedString *mas = [self.attributedText mutableCopy];
for (NSTextCheckingResult* result in resultString)
{
if (result.resultType == NSTextCheckingTypeLink)
{
NSRange intersection = NSIntersectionRange(result.range, self.rangeOfLink);
if (intersection.length <= 0) // no match
[mas addAttribute: NSForegroundColorAttributeName
value: [UIColor blueColor]
range: self.rangeOfLink];
else
[mas addAttribute: NSForegroundColorAttributeName
value: [UIColor redColor]
range: self.rangeOfLink];
}
}
self.attributedText = mas;
}
}
[super drawRect: rect];
现在如果textView有多个link,只有被选中的会改变颜色。
我有一个带有多个 URL 的 UITextView
,我通过将 dataDetectorTypes
属性 设置为 UIDataDetectorTypeLink
来激活它们。然后我使用 linkTextAttributes
属性 来设置 link 的颜色。现在,当用户点击 link 之一(使用 UITapGestureRecognizer
)时,我只想更改 link 的颜色。如果我改变 linkTextAttributes
,所有 link 都会改变颜色。
我怎样才能只改变被点击的 link 的颜色?
如果这些网址是固定的。 例如: 我有以下网址:
我会将它们放入 NSAttributedString 使用 NSMutableAttributedString 将它们全部组合起来
NSMutableAttributedString *urlsAttributedText = [[NSMutableAttributedString alloc]init];
NSAttributedString *url1 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.123.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
NSAttributedString *url2 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.456.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor greenColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
NSAttributedString *url3 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.789.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor redColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
[urlsAttributedText url1];
[urlsAttributedText appendAttributedString:url2];
[urlsAttributedText appendAttributedString:url3];
self.texView.attributedText = urlsAttributedText;
干杯!
我想我解决了它,使用名为 UITextView
的子类,它有一个 rangeOfLink
属性.
首先,在我的 UIViewController
viewDidLoad:
中,我添加
self.textView.dataDetectorTypes = UIDataDetectorTypeLink; // change for other link types
self.textView.selectable = YES;
self.textView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(handleTap:)];
tapGesture.cancelsTouchesInView = YES;
[self.textView addGestureRecognizer: tapGesture];
[self.textView setNeedsDisplay]; // force a redraw so that drawRect is called
然后在 handleTap
中,我这样做:
MyTextViewWithLink *aTextView = (IDTextViewWithLink *) recognizer.view;
if (aTextView != self.textView)
return;
if (recognizer.state == UIGestureRecognizerStateEnded)
{
CGPoint location = [recognizer locationInView: aTextView];
// this returns an NSTextCheckingResult if location is inside a link
NSTextCheckingResult *result = [self textCheckingResultAtPoint: location inTextView: aTextView];
if (result)
{
aTextView.rangeOfLink = result.range;
[aTextView setNeedsDisplay]; // this will force the color change
// open url
}
}
最后我在我的 UITextView
子类中覆盖了 drawRect
:
self.linkTextAttributes = [NSDictionary dictionary];
NSError *error = nil;
NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error: &error]; // change for other link types
if (!error && dataDetector)
{
NSArray* resultString = [dataDetector matchesInString: self.text
options: NSMatchingReportProgress
range: NSMakeRange(0, [self.text length])];
if (resultString.count > 0)
{
NSMutableAttributedString *mas = [self.attributedText mutableCopy];
for (NSTextCheckingResult* result in resultString)
{
if (result.resultType == NSTextCheckingTypeLink)
{
NSRange intersection = NSIntersectionRange(result.range, self.rangeOfLink);
if (intersection.length <= 0) // no match
[mas addAttribute: NSForegroundColorAttributeName
value: [UIColor blueColor]
range: self.rangeOfLink];
else
[mas addAttribute: NSForegroundColorAttributeName
value: [UIColor redColor]
range: self.rangeOfLink];
}
}
self.attributedText = mas;
}
}
[super drawRect: rect];
现在如果textView有多个link,只有被选中的会改变颜色。