Actualizar:
Había 2 partes clave en mi pregunta:
- Cómo hacer un enlace donde el texto que se muestra para el enlace en el que se puede hacer clic es diferente del enlace real que se invoca:
- Cómo configurar los enlaces sin tener que usar un código personalizado para establecer los atributos en el texto.
Resulta que iOS 7 agregó la capacidad de cargar texto atribuido desde NSData .
Creé una subclase personalizada UITextViewque aprovecha la@IBInspectable atributo y le permite cargar contenido de un archivo RTF directamente en IB. Simplemente escriba el nombre del archivo en IB y la clase personalizada hace el resto.
Aquí están los detalles:
En iOS 7, NSAttributedStringganó el método initWithData:options:documentAttributes:error:. Ese método le permite cargar una NSAttributedString desde un objeto NSData. Primero puede cargar un archivo RTF en NSData, luego usarlo initWithData:options:documentAttributes:error:para cargar ese NSData en su vista de texto. (Tenga en cuenta que también hay un método initWithFileURL:options:documentAttributes:error:que cargará una cadena atribuida directamente desde un archivo, pero ese método se desaprobó en iOS 9. Es más seguro usar el método initWithData:options:documentAttributes:error:, que no se desaprobó.
Quería un método que me permitiera instalar enlaces clicables en mis vistas de texto sin tener que crear ningún código específico para los enlaces que estaba usando.
La solución que se me ocurrió fue crear una subclase personalizada de UITextView a la que llamo RTF_UITextViewy asignarle una @IBInspectablepropiedad llamada RTF_Filename. Agregar el @IBInspectableatributo a una propiedad hace que Interface Builder exponga esa propiedad en el "Inspector de atributos". Luego puede establecer ese valor desde IB sin código personalizado.
También agregué un @IBDesignableatributo a mi clase personalizada. El @IBDesignableatributo le dice a Xcode que debe instalar una copia en ejecución de su clase de vista personalizada en el generador de interfaces para que pueda verla en la visualización gráfica de su jerarquía de vistas. () Desafortunadamente, para esta clase, la @IBDesignablepropiedad parece ser escamosa. Funcionó cuando lo agregué por primera vez, pero luego eliminé el contenido de texto sin formato de mi vista de texto y los enlaces en los que se puede hacer clic desaparecieron y no he podido recuperarlos).
El código para mi RTF_UITextViewes muy simple. Además de agregar el @IBDesignableatributo y una RTF_Filenamepropiedad con el @IBInspectableatributo, agregué un didSet()método a la RTF_Filenamepropiedad. El didSet()método se llama cada vez que RTF_Filenamecambia el valor de la propiedad. El código para el didSet()método es bastante simple:
@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.");
}
}
}
}
}
Tenga en cuenta que si la propiedad @IBDesignable no le permitirá obtener una vista previa de su texto con estilo en el generador de interfaces, entonces sería mejor configurar el código anterior como una extensión de UITextView en lugar de una subclase personalizada. De esa manera, podría usarlo en cualquier vista de texto sin tener que cambiar la vista de texto a la clase personalizada.
Vea mi otra respuesta si necesita admitir versiones de iOS anteriores a iOS 7.
Puede descargar un proyecto de muestra que incluye esta nueva clase desde gitHub:
Proyecto de demostración DatesInSwift en Github