swift: HTML-данные, преобразованные в строку NSAttributed, не делают ссылки активными в ярлыке - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть текст в формате HTML. Я использую свойство строки NSAttributed для его анализа. Он хорошо разбирает текст и отображается на этикетке. Однако разбор тега привязки не делает ссылку доступной для клика. Это следующий код, который я использую для анализа.

extension String {
var htmlToAttributedString: NSAttributedString? {
    guard let data = data(using: .utf8) else { return NSAttributedString() }
    do {
        return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
    } catch {
        return NSAttributedString()
    }
}
var htmlToString: String {
    return htmlToAttributedString?.string ?? ""
}

Когда я запускаю приложение и присваиваю метке значение:

text = "<p>This is <a href=\"http://www.google.com\">Google Home</a></p>"
simpleTextLabel.attributedText = text.htmlToAttributedString

Вывод в приложении iOS выглядит следующим образом, но при нажатии ничего не происходит:

Это Google Home .

Как мне открыть его в сафари?

1 Ответ

1 голос
/ 26 апреля 2019

С вашей строки:

simpleTextLabel.attributedText = text.htmlToAttributedString

Мы можем предположить, что simpleTextLabel - это UILabel.

Это базовое поведение от UILabel - не быть "интерактивным".Вы можете добавить к нему жест касания, но он преобразуется в UIButton.

Существуют некоторые приемы, позволяющие сделать это с помощью UILabel, найти, где именно он был нажат, проверить, есть лиэто ссылка и т. д. Ищем «UILabel Clickable»: Создать «ссылки» с возможностью нажатия в NSAttributedString UILabel? и т. д. Есть даже несколько сторонних библиотек.

Я (по моему скромному мнению) считаю это "взломом".

Есть хорошая Сессия WWDC 2018: TextKit Best Practices ,В 2:34 это объясняет, что если вам нужно взаимодействовать с отображаемым текстом, предпочитает UITextView вместо UILabel.

Для этого есть метод UITextViewDelegate: textView(_:shouldInteractWith:in:interaction:)

Обратите внимание, что есть небольшие различия в рендеринге UITextView и UILabel.Если вы наложите их, они не будут иметь одинаковую «начальную точку», макет будет немного другим.Однако с небольшими изменениями он может быть таким же (например: Как сделать текст макета UITextView таким же, как UILabel? ).

Обратите внимание, что в соответствии с маленькимИзменяя UITextView в UILabel визуальном рендеринге, пользователь не заметит разницы (и это действительно важно, кроме того, что использование нативных методов UITextView / UITextViewDelegate делает его легко понятным впоследствиидругой разработчик, или через несколько месяцев, если вам нужно сделать небольшую модификацию).

...