Обновить:
На мой вопрос было 2 ключевых части:
- Как создать ссылку, в которой текст, отображаемый для кликабельной ссылки, отличается от действительной ссылки, которая вызывается:
- Как настроить ссылки без использования специального кода для установки атрибутов в тексте.
Оказывается, в iOS 7 добавлена возможность загрузки атрибутивного текста из NSData
.
Я создал собственный подкласс, UITextView
который использует @IBInspectable
атрибут и позволяет загружать содержимое из файла RTF непосредственно в IB. Вы просто вводите имя файла в IB, а пользовательский класс делает все остальное.
Вот подробности:
В iOS 7 NSAttributedString
получил метод initWithData:options:documentAttributes:error:
. Этот метод позволяет загрузить NSAttributedString из объекта NSData. Вы можете сначала загрузить файл RTF в NSData, а затем использовать initWithData:options:documentAttributes:error:
для загрузки этих NSData в ваше текстовое представление. (Обратите внимание, что есть также метод, initWithFileURL:options:documentAttributes:error:
который будет загружать атрибутированную строку непосредственно из файла, но этот метод устарел в iOS 9. Безопаснее использовать метод initWithData:options:documentAttributes:error:
, который не устарел.
Я хотел метод, который позволял бы мне устанавливать кликабельные ссылки в моих текстовых представлениях без необходимости создавать какой-либо код, специфичный для ссылок, которые я использовал.
Решение, которое я придумал, состояло в том, чтобы создать собственный подкласс UITextView, который я вызываю, RTF_UITextView
и присвоить ему @IBInspectable
свойство с именем RTF_Filename
. Добавление @IBInspectable
атрибута к свойству заставляет Интерфейсный Разработчик выставить это свойство в «Инспекторе Атрибутов». Затем вы можете установить это значение из IB без специального кода.
Я также добавил @IBDesignable
атрибут в свой пользовательский класс. @IBDesignable
Атрибут сообщает Xcode , что он должен установить запущенную копию пользовательского класса представления в строитель интерфейс , так что вы можете увидеть его в графическом дисплее вашего зрения иерархии. () К сожалению, для этого класса @IBDesignable
свойство выглядит нечетким. Это сработало, когда я впервые добавил его, но затем я удалил текстовое содержимое моего текстового представления, и кликабельные ссылки в моем представлении исчезли, и я не смог их вернуть.)
Код для моего RTF_UITextView
очень прост. Помимо добавления @IBDesignable
атрибута и RTF_Filename
свойства с @IBInspectable
атрибутом, я добавил didSet()
метод к RTF_Filename
свойству. didSet()
Метод вызывается каждый раз , когда значение RTF_Filename
свойства изменяется. Код для didSet()
метода довольно прост:
@IBDesignable
class RTF_UITextView: UITextView
{
@IBInspectable
var RTF_Filename: String?
{
didSet(newValue)
{
//If the RTF_Filename is nil or the empty string, don't do anything
if ((RTF_Filename ?? "").isEmpty)
{
return
}
//Use optional binding to try to get an URL to the
//specified filename in the app bundle. If that succeeds, try to load
//NSData from the file.
if let fileURL = NSBundle.mainBundle().URLForResource(RTF_Filename, withExtension: "rtf"),
//If the fileURL loads, also try to load NSData from the URL.
let theData = NSData(contentsOfURL: fileURL)
{
var aString:NSAttributedString
do
{
//Try to load an NSAttributedString from the data
try
aString = NSAttributedString(data: theData,
options: [:],
documentAttributes: nil
)
//If it succeeds, install the attributed string into the field.
self.attributedText = aString;
}
catch
{
print("Nerp.");
}
}
}
}
}
Обратите внимание, что если свойство @IBDesignable не позволяет надежно предварительно просматривать стилизованный текст в Интерфейсном конструкторе, то может быть лучше установить приведенный выше код как расширение UITextView, а не как пользовательский подкласс. Таким образом, вы можете использовать его в любом текстовом представлении, не меняя текстовое представление на пользовательский класс.
Смотрите мой другой ответ, если вам нужно поддерживать версии iOS до iOS 7.
Вы можете скачать пример проекта, который включает этот новый класс, из gitHub:
Демонстрационный проект DatesInSwift на Github