UILabel - 文本和链接的字符串

71

我有一个UILabel,它的文本内容是从服务器获取的。其中一些文本需要被识别为链接,当点击这些链接时,应该执行某些操作。例如:

NSString *str = @"My phone number is 645-345-2345 and my address is xyz";

上面是UILabel的完整文本。我只有一个UILabel用于显示这个文本(文本是动态的,这里只是举个例子)。当点击这些链接时,我需要执行如导航到不同的屏幕或打电话等操作。
我知道可以用OHAttributedLabel来显示这种文本,链接可以如下显示:

[label1 addCustomLink:[NSURL URLWithString:@"http://www.foodreporter.net"] inRange:[txt rangeOfString:someString]];  

我想知道如何将这些文本链接变成可以执行某些操作,比如导航到不同的屏幕或打电话。
如果需要更多解释,请告诉我。


1
从2013年开始...你只需要使用UITextView并在interfaceBuilder中点击“检测链接”...就这么简单。 - Fattie
https://dev59.com/42LVa4cB1Zd3GeqPx5hh - kernix
6个回答

130

你可以为支持链接的任何可用UILabel替代品添加自定义操作,使用一种URL方案,稍后您将拦截它:

TTTAttributedLabel *tttLabel = <# create the label here #>;
NSString *labelText = @"Lost? Learn more.";
tttLabel.text = labelText;
NSRange r = [labelText rangeOfString:@"Learn more"]; 
[tttLabel addLinkToURL:[NSURL URLWithString:@"action://show-help"] withRange:r];

接下来,在你的TTTAttributedLabelDelegate中:

- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url {
    if ([[url scheme] hasPrefix:@"action"]) {
        if ([[url host] hasPrefix:@"show-help"]) {
            /* load help screen */
        } else if ([[url host] hasPrefix:@"show-settings"]) {
            /* load settings screen */
        }
    } else {
        /* deal with http links here */
    }
}

TTTAttributedLabel是OHAttributedLabel的一个分支。

如果您需要更复杂的方法,可以查看Nimbus Attributed Label。它支持开箱即用的自定义链接。


4
补充一下:自定义URL需要带有//,例如action://show-help。否则,方案将是唯一有效的URL属性。(没有双斜杠,其他所有内容都将为nil)。 - Dima
非常感谢,我已经将标签属性化并将链接插入到特定范围中。但是我无法更改它的字体大小。请帮忙。 - Khalid Usman
2
有没有针对iOS 6+的新方法?因为UILabel支持attributedStrings。 - João Nunes
tttattributedLabel源代码在github上不可用,是否有替代方案? - Raghav
@Raghav 你可以在这里找到TTTAttributedLabel https://github.com/mattt/TTTAttributedLabel 经过数小时的搜索终于找到了,呼~~~ - iYoung
显示剩余3条评论

17
你可以使用 UITextView 来检测电话号码和链接(Phone numbers and links detection), 禁用滚动(scrolling disabled),启用用户交互(user interaction enabled),而不是使用 UILabel。

从2013年开始... 就是这么简单。 - Fattie
1
@Ganesh,为什么禁用了滚动? - brainjam

8
我的项目已经成功地使用了OHAttributedLabel进行了相关处理。请查看OHAttributedLabelDelegate中的方法-(BOOL)attributedLabel:(OHAttributedLabel*)attributedLabel shouldFollowLink:(NSTextCheckingResult*)linkInfo; (链接)。它允许你决定当用户点击链接时发生什么事情。如果你查看OHAttributedLabel项目的示例源代码,你就可以看到它是用来显示警报的。如果你在这种情况下返回NO(以保持默认操作不会发生),那么你可以做任何你想做的事情,如导航等。
然而请注意,这需要你可以正确地从文本中确定行动。对于我们的项目,我们使用了稍微高级一些的解决方案,其中服务器向我们发送带有标签的文本和每个标签要执行的命令列表。

6
有一个名为FancyLabel的项目,与您所需的内容相关。不过可能需要一些定制。 此外,我认为Three20也具备这种功能,但如果您还没有使用它,那么可能会过度设计。
如果您所有的链接都是电话号码、地址或网址,那么还有一个更简单的解决方案。您可以使用UITextView而不是UILabel。它具有自动检测电话、地址等功能(只需在IB中勾选相应的框)。
您还可以通过重写openURL来对这些链接的点击事件进行自定义操作,如此处所述。
是否有特别的原因必须使用UILabel而不是UITextView?请注意,很多带属性标签的实现都继承自UIView或者没有实现UILabel的所有功能。

3

您可以使用自定义按钮来使其看起来像链接。如果您不想使用按钮,还可以在自定义标签上添加手势。

UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTappedOnLink:)];
// if labelView is not set userInteractionEnabled, you must do so
[labelView setUserInteractionEnabled:YES];
[labelView addGestureRecognizer:gesture];

我只能使用单个标签,不能放置按钮。 - Nitish
请您能否解释一下您的第二个选项。它可能在这里很有用。 - Nitish
问题在于链接在标签上的位置不同,而且这些位置是动态的。这种方法对我有用吗? - Nitish

3

当我只需要一个轻量级标签来呈现链接(并告诉我何时被点击)时,被强制使用UITextView或第三方库,我并不是很喜欢。

这里是我的一个尝试,它是一个轻量级的UILabel子类,能够检测到链接的点击。与其他方法不同的是,它通过在NSTextStorage中添加一个委托回调来获得访问UILabel共享的NSLayoutManager。优美的地方在于,UILabel执行其本地布局和绘图 - 其他UILabel替换通常会增强或替换本地行为,并添加额外的NSLayoutManager/NSTextContainer

可能可以安全地发布到App Store,但有点脆弱 - 使用时自担风险!

https://github.com/TomSwift/TSLabel


它没有自动检测。 - Nike Kov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接