Aktualizacja:
Moje pytanie zawierało 2 kluczowe części:
- Jak utworzyć łącze, w którym tekst wyświetlany dla łącza, który można kliknąć, różni się od rzeczywistego wywołanego łącza:
- Jak skonfigurować łącza bez konieczności używania niestandardowego kodu w celu ustawienia atrybutów w tekście.
Okazuje się, że iOS 7 dodał możliwość ładowania przypisanego tekstu NSData
.
Stworzyłem niestandardową podklasę, UITextView
która korzysta z@IBInspectable
atrybutu i pozwala ładować zawartość z pliku RTF bezpośrednio w IB. Po prostu wpisz nazwę pliku w IB, a klasa niestandardowa zajmie się resztą.
Oto szczegóły:
W iOS 7 NSAttributedString
uzyskał tę metodę initWithData:options:documentAttributes:error:
. Ta metoda pozwala załadować NSAttributString z obiektu NSData. Możesz najpierw załadować plik RTF do NSData, a następnie użyć initWithData:options:documentAttributes:error:
do załadowania tego NSData do widoku tekstowego. (Należy pamiętać, że istnieje również metoda initWithFileURL:options:documentAttributes:error:
, która załaduje przypisany ciąg bezpośrednio z pliku, ale ta metoda została wycofana w iOS 9. Bezpieczniej jest użyć tej metody initWithData:options:documentAttributes:error:
, która nie była przestarzała.
Chciałem metody, która pozwoli mi zainstalować klikalne linki w moich widokach tekstowych bez konieczności tworzenia kodu specyficznego dla linków, których używałem.
Rozwiązaniem, które wymyśliłem, było utworzenie niestandardowej podklasy wywoływanej przez UITextView RTF_UITextView
i nadanie jej @IBInspectable
właściwości o nazwie RTF_Filename
. Dodawanie@IBInspectable
atrybutu do właściwości powoduje, że Konstruktor interfejsu ujawnia tę właściwość w „Inspektorze atrybutów”. Następnie możesz ustawić tę wartość z IB bez kodu niestandardowego.
Dodałem również @IBDesignable
atrybut do mojej klasy niestandardowej. @IBDesignable
Atrybut Xcode mówi, że powinien on zainstalować uruchomioną kopię widoku niestandardowego interfejsu klasy do konstruktora, więc można zobaczyć go w graficznym wyświetlaczu widzenia hierarchii. () Niestety, dla tej klasy @IBDesignable
właściwość wydaje się niestabilna. Działało, kiedy go po raz pierwszy dodałem, ale potem usunąłem zwykły tekst z mojego widoku tekstowego, a klikalne łącza w moim widoku zniknęły i nie byłem w stanie ich odzyskać).
Mój kod RTF_UITextView
jest bardzo prosty. Oprócz dodania @IBDesignable
atrybutu i RTF_Filename
właściwości do @IBInspectable
atrybutu dodałem didSet()
metodę do RTF_Filename
właściwości. didSet()
Metoda jest wywoływana w dowolnym momencie wartość RTF_Filename
zmian własności. Kod didSet()
metody jest dość prosty:
@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.");
}
}
}
}
}
Zauważ, że jeśli właściwość @IBDesignable nie pozwoli w niezawodny sposób wyświetlić podglądu stylizowanego tekstu w Konstruktorze interfejsów, może być lepiej ustawić powyższy kod jako rozszerzenie UITextView zamiast niestandardowej podklasy. W ten sposób można go używać w dowolnym widoku tekstu bez konieczności zmiany widoku tekstu na klasę niestandardową.
Zobacz moją inną odpowiedź, jeśli potrzebujesz obsługiwać wersje iOS wcześniejsze niż iOS 7.
Możesz pobrać przykładowy projekt zawierający tę nową klasę z gitHub:
Projekt demonstracyjny DatesInSwift na Github