亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在UILabel的NSAttributedString中創建可點擊的“鏈接”?

在UILabel的NSAttributedString中創建可點擊的“鏈接”?

largeQ 2019-06-20 16:36:56
在UILabel的NSAttributedString中創建可點擊的“鏈接”?我已經找了好幾個小時了,但我失敗了。我可能都不知道該找什么了。許多應用程序都有文本,在這篇文章中,Web超鏈接是四舍五入的RECT。當我點擊它們UIWebView打開。令我困惑的是,它們通常都有自定義鏈接,例如,如果單詞以#開頭,它也是可點擊的,應用程序通過打開另一個視圖來響應。我怎么能這么做?有沒有可能UILabel還是我需要UITextView還是別的什么?
查看完整描述

3 回答

?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

一般來說,如果我們想在UILabel顯示的文本中有一個可點擊的鏈接,我們需要解決兩個獨立的任務:

  1. 更改部分文本的外觀,使其看起來像鏈接
  2. 檢測和處理鏈接上的觸摸(打開URL是一種特殊情況)

第一個很簡單。從iOS 6開始,UILabel支持顯示屬性字符串。您所需要做的就是創建和配置NSMutableAttributedString實例:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4); // for the word "link" in the string aboveNSDictionary *linkAttributes = 
@{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
                                  NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
                                  [attributedString setAttributes:linkAttributes range:linkRange];
                                  // Assign attributedText to UILabellabel.attributedText = attributedString;

就這樣!上面的代碼使UILabel顯示字符串具有鏈接

現在我們應該檢測到這個鏈接的觸點。這樣做的目的是捕捉UILabel中的所有點擊,并確定點擊的位置是否足夠接近鏈接。為了捕捉觸摸,我們可以添加點擊手勢識別器到標簽。確保為標簽啟用userInteraction,默認情況下它被關閉:

label.userInteractionEnabled = YES;[label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:
self action:@selector(handleTapOnLabel:)]];

現在,最復雜的東西:找出點擊是否在鏈接顯示的位置,而不是在標簽的任何其他部分。如果我們有單行UILabel,這個任務可以通過硬編碼顯示鏈接的區域邊界來相對容易地解決,但是讓我們更優雅地解決這個問題,對于一般情況-多行UILabel,不需要對鏈接布局有初步的了解。

其中一種方法是使用IOS 7中引入的文本工具包API的功能:

// Create instances of NSLayoutManager, NSTextContainer and NSTextStorageNSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];NSTextStorage *textStorage = [[NSTextStorage alloc] 
initWithAttributedString:attributedString];// Configure layoutManager and textStorage[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];// Configure textContainertextContainer.lineFragmentPadding = 0.0;textContainer.lineBreakMode
 = label.lineBreakMode;textContainer.maximumNumberOfLines = label.numberOfLines;

在類中的屬性中保存已創建和配置的NSLayoutManager、NSTextContainer和NSTextStorage實例(很可能是UIViewController的后代)-我們將在其他方法中使用它們。

現在,每當標簽更改其框架時,更新TextContainer的大?。?/trans>

- (void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    self.textContainer.size = self.label.bounds.size;}

最后,檢測點擊是否正好在鏈接上:

- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture{
    CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
    CGSize labelSize = tapGesture.view.bounds.size;
    CGRect textBoundingBox = [self.layoutManager usedRectForTextContainer:self.textContainer];
    CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
                                              
                            (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
    CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
                                                         locationOfTouchInLabel.y - textContainerOffset.y);
    NSInteger indexOfCharacter = [self.layoutManager characterIndexForPoint:locationOfTouchInTextContainer
                                                            inTextContainer:self.textContainer
                                   fractionOfDistanceBetweenInsertionPoints:nil];
    NSRange linkRange = NSMakeRange(14, 4);
     // it's better to save the range somewhere when it was originally used for marking link in attributed string
    if (NSLocationInRange(indexOfCharacter, linkRange)) {
        // Open an URL, or handle the tap on the link in any other way
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]];
    }}


查看完整回答
1 反對 回復 2019-06-20
  • 3 回答
  • 0 關注
  • 3057 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號