Гиперссылки в UITextView

Я пытаюсь создать UITextView с hyperlink чтобы, когда пользователь нажимает на ссылку, его UITextView в safari чтобы открыть веб-страницу. Я читал о детекторах ссылок для просмотра textview но в этих примерах всегда показано, как работает определение ссылок, если в тексте присутствует фактическая ссылка (например, www.google.com). Я хочу, чтобы это был обычный текст, который при нажатии открывает связанный URL. (т.е. Google - это текст, и при нажатии открывается URL-адрес www.google.com). Как я могу сделать это в iOS7/8?

Ответ 1

Используйте NSAttributedString

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:@"Google" 
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
self.textView.attributedText = attributedString;

Конечно, вы можете установить только часть текста как ссылку. Подробнее о NSAttributedString здесь.

Если вы хотите получить больше контроля и сделать что-то, прежде чем открывать ссылку. Вы можете установить делегат в UITextView.

- (void)viewDidLoad {
    ...
    self.textView.delegate = self; // self must conform to UITextViewDelegate protocol
}

...

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    // Do whatever you want here
    NSLog(@"%@", URL); // URL is an instance of NSURL of the tapped link
    return YES; // Return NO if you don't want iOS to open the link
}

Ответ 2

Swift 3, iOS10, Xcode 9

Ответ @sikhapol действительно хорош, если вы точно знаете слова, которые хотите разобрать, например, словарь слов.

это все о самой строке, которая отображается в UITextView

Мое решение основано на рендеринге текста, если вы заставляете UITextView отображать HTML-теги, вы можете использовать тег href.

Вот некоторые ссылки на код, которые вы можете использовать

Сначала вам нужно настроить UITextView из конструктора интерфейса или кода формы для

  1. Выбор
  2. Данные детекторов

Примечание: не делайте текстовое представление редактируемым

Интерфейсный конструктор

enter image description here

программно

         let htmlData = NSString(string: "go to <a href=\"http://www.google.com\">google</a> and search for it").data(using: String.Encoding.unicode.rawValue)


        let attributedString = try! NSAttributedString(data: htmlData!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
        yourUIViewView.isSelectable = true
        yourUIViewView.dataDetectorTypes = .link
        yourUIViewView.attributedText = attributedString
        yourUIViewView.delegate = self

для UITextViewDelegate

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

       // check for the url string for performing your own custom actions here
      let urlString = URL.absoluteString

       // Return NO if you don't want iOS to open the link
        return true
     }

Ответ 3

если вы хотите использовать активную подстроку в своем UITextView, вы можете использовать мой расширенный TextView... его короткий и простой. Вы можете отредактировать его, как хотите.

как использовать (range = substring location):

[self.textView addTapActionWithRange:range withActionBlock:^{
      // anything you want to do - show something
}];

Результат: введите описание изображения здесь

исходный код: https://github.com/marekmand/ActiveSubstringTextView

Ответ 4

В этом примере кода есть две разные ссылки на одном и том же ярлыке, а цвет URL установлен так, чтобы избежать синего по умолчанию.

UITextView * textTerm = [UITextView new];
NSMutableAttributedString *attrRight = [[NSMutableAttributedString alloc] initWithString:@"Terms of Service"
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
NSMutableAttributedString *attrLeft = [[NSMutableAttributedString alloc] initWithString:@"Privacy Policy"
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
[attrRight appendAttributedString:attrLeft];
textTerm.attributedText = attrRight;
textTerm.editable = NO;
textTerm.dataDetectorTypes = UIDataDetectorTypeAll;
textTerm.linkTextAttributes = [UIColor whiteColor];
textTerm.backgroundColor = [UIColor clearColor];

Ответ 5

Изящное маленькое расширение, которое я написал и использую (Swift 4.2, протестировано на iOS 12.1)

extension NSAttributedString {
    func replace(placeholder: String, with hyperlink: String, url: String) -> NSAttributedString {
        let mutableAttr = NSMutableAttributedString(attributedString: self)

        let hyperlinkAttr = NSAttributedString(string: hyperlink, attributes: [NSAttributedString.Key.link: URL(string: url)!])

        let placeholderRange = (self.string as NSString).range(of: placeholder)

        mutableAttr.replaceCharacters(in: placeholderRange, with: hyperlinkAttr)
        return mutableAttr
    }
}

Использование:

//Set through code or through interface builder
footerText.isSelectable = true
footerText.dataDetectorTypes = .link

//Keeps the original formatting from xib or storyboard
footerText.text = "By continuing, you are indicating that you accept our @[email protected] and @[email protected]"
footerText.attributedText = footerText.attributedText?
        .replace(placeholder: "@[email protected]", with: "Terms and Conditions", url: AppUrl.terms)
        .replace(placeholder: "@[email protected]", with: "Privacy Policy", url: AppUrl.privacy)