Оновлення:
У моєму питанні було дві ключові частини:
- Як створити посилання, коли текст, який відображається для посилання, на який можна натискати, відрізняється від фактичного посилання, на яке викликається:
- Як налаштувати посилання без використання спеціального коду для встановлення атрибутів у тексті.
Виявляється, 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
атрибуту до властивості змушує Інтерфейс Builder викрити цю властивість у "Ревізорі атрибутів". Потім ви можете встановити це значення з 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