Atualizar:
Havia duas partes principais da minha pergunta:
- Como criar um link em que o texto mostrado para o link clicável seja diferente do link real que é chamado:
- Como configurar os links sem precisar usar código personalizado para definir os atributos no texto.
Acontece que o iOS 7 adicionou a capacidade de carregar o texto atribuído NSData.
Criei uma subclasse personalizada UITextViewque aproveita o @IBInspectableatributo e permite carregar o conteúdo de um arquivo RTF diretamente no IB. Você simplesmente digita o nome do arquivo no IB e a classe personalizada faz o resto.
Aqui estão os detalhes:
No iOS 7, NSAttributedStringganhou o métodoinitWithData:options:documentAttributes:error: . Esse método permite carregar um NSAttributedString a partir de um objeto NSData. Você pode primeiro carregar um arquivo RTF no NSData e depois usá-lo initWithData:options:documentAttributes:error:para carregá-lo na exibição de texto. (Observe que também há um método initWithFileURL:options:documentAttributes:error:que carrega uma sequência atribuída diretamente de um arquivo, mas esse método foi preterido no iOS 9. É mais seguro usar o método initWithData:options:documentAttributes:error:, que não foi preterido.
Eu queria um método que me permitisse instalar links clicáveis nos meus modos de exibição de texto sem precisar criar nenhum código específico para os links que eu estava usando.
A solução que encontrei foi criar uma subclasse personalizada do UITextView que eu chamo RTF_UITextViewe fornecer uma@IBInspectable propriedade chamada RTF_Filename. A adição do @IBInspectableatributo a uma propriedade faz com que o Interface Builder exponha essa propriedade no "Attributes Inspector". Em seguida, você pode definir esse valor no IB sem código personalizado.
Também adicionei um @IBDesignableatributo à minha classe personalizada. o@IBDesignable atributo diz ao Xcode que ele deve instalar uma cópia em execução da sua classe de visualização customizada no construtor Interface, para que você possa vê-la na exibição gráfica da sua hierarquia de visualizações. () Infelizmente, para esta classe, a @IBDesignablepropriedade parece ser esquisita. Funcionou quando o adicionei pela primeira vez, mas excluí o conteúdo de texto sem formatação da minha exibição de texto e os links clicáveis desapareceram e não consegui recuperá-los.)
O código para o meu RTF_UITextViewé muito simples. Além de adicionar o @IBDesignableatributo e uma RTF_Filenamepropriedade ao @IBInspectableatributo, adicionei um didSet()método à RTF_Filenamepropriedade O didSet()método é chamado sempre que o valor da RTF_Filenamepropriedade é alterado. O código para o didSet()método é bastante simples:
@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.");
}
}
}
}
}
Observe que, se a propriedade @IBDesignable não permitir a visualização confiável do texto com estilo no construtor de interface, será melhor configurar o código acima como uma extensão do UITextView em vez de uma subclasse personalizada. Dessa forma, você pode usá-lo em qualquer visualização de texto sem precisar alterar a visualização de texto para a classe personalizada.
Veja minha outra resposta se precisar oferecer suporte a versões do iOS anteriores ao iOS 7.
Você pode baixar um projeto de amostra que inclua essa nova classe no gitHub:
Projeto de demonstração DatesInSwift no Github