Szukałem tego od wielu godzin, ale mi się nie udało. Prawdopodobnie nawet nie wiem, czego powinienem szukać.
Wiele aplikacji ma tekst, a w tym tekście są hiperłącza internetowe w zaokrąglonym prostokącie. Po kliknięciu UIWebView
otwiera się. Zastanawia mnie to, że często mają niestandardowe linki, na przykład jeśli słowa zaczynają się od #, można je również kliknąć, a aplikacja odpowiada otwierając inny widok. Jak mogę to zrobić? Czy jest to możliwe, UILabel
czy potrzebuję UITextView
czy czegoś innego?
ios
hyperlink
uilabel
nsattributedstring
uitapgesturerecognizer
Biec susami
źródło
źródło
Swift 4
rozwiązania. Używa,UITextView
ale sprawia, że zachowuje się jakUILabel
. Wypróbowałem tutaj rozwiązania i nie udało mi się uzyskać dokładnego wykrywania łącza.Odpowiedzi:
Ogólnie, jeśli chcemy mieć klikalny link w tekście wyświetlany przez UILabel, musielibyśmy rozwiązać dwa niezależne zadania:
Pierwszy jest łatwy. Począwszy od iOS 6 UILabel obsługuje wyświetlanie przypisanych ciągów. Wszystko, co musisz zrobić, to utworzyć i skonfigurować instancję NSMutableAttributString:
Otóż to! Powyższy kod powoduje, że UILabel wyświetla String wraz z linkiem
Teraz powinniśmy wykryć poprawki tego linku. Chodzi o to, aby złapać wszystkie krany w UILabel i dowiedzieć się, czy lokalizacja kranu była wystarczająco blisko linku. Aby złapać akcenty, możemy dodać do etykiety rozpoznawanie gestów dotykowych. Pamiętaj, aby włączyć etykietę UserInteraction dla etykiety, jest ona domyślnie wyłączona:
Teraz najbardziej wyrafinowane rzeczy: sprawdzenie, czy kran był w miejscu, w którym wyświetlany jest link, a nie w żadnej innej części etykiety. Gdybyśmy mieli UILabel z pojedynczą linią, zadanie to można by rozwiązać stosunkowo łatwo, na stałe zakreślając granice obszaru, w którym wyświetlany jest link, ale rozwiążmy ten problem bardziej elegancko i ogólnie - wielowierszowy UILabel bez wstępnej wiedzy o układzie łącza.
Jednym z podejść jest wykorzystanie możliwości Text Kit API wprowadzonych w iOS 7:
Zapisz utworzone i skonfigurowane instancje NSLayoutManager, NSTextContainer i NSTextStorage we właściwościach w swojej klasie (najprawdopodobniej potomek UIViewController) - będziemy potrzebować ich w innych metodach.
Teraz za każdym razem, gdy etykieta zmienia ramkę, aktualizuj tekst Rozmiar kontenera:
Na koniec sprawdź, czy kran był dokładnie na linku:
źródło
cellForRowAtIndexPath
? Tworzę i konfiguruję instancje wewnątrzcellForRowAtIndexPath
i hostuję równieżhandleTapOnLabel
funkcję w nim zawartą. Ale ocell.textLabel.addGestureRecognizer(UITapGestureRecognizer(target: cell, action: "handleTapOnLabel:"))
, rozumiemunrecognized selector
.textAlignment
atrybut etykiety jest ustawiony naNSTextAlignmentCenter
. Jeśli używasz tekstu niepośrodkowanego, musisz dostosować obliczeniatextContainerOffset
w powyższym kodzie.x
wartości używana jesttextContainerOffset
stała0.5
. To obliczy prawidłową pozycję dlaNSTextAlignmentCenter
. Aby wyrównać do lewej, naturalny lub wyrównany, użyj wartości0.0
. Aby wyrównać do prawej, użyj1.0
.Mam rozszerzenie @NAlexN oryginalny szczegółowe rozwiązania, z @zekel doskonałe rozszerzenie
UITapGestureRecognizer
i zapewnienie w Swift .Rozszerzanie UITapGestureRecognizer
Stosowanie
Skonfiguruj
UIGestureRecognizer
wysyłanie akcji dotapLabel:
i możesz wykryć, czy zakresy docelowe są wykorzystywanemyLabel
.WAŻNE:
UILabel
Tryb podziału linii musi być ustawiony na zawijanie przez słowo / znak. W jakiś sposób założy,NSTextContainer
że tekst jest jednowierszowy, tylko jeśli tryb podziału linii jest inny.źródło
targetRange1
itargetRange2
.NSMutableAttributedString(attributedString: text)
gdzie jest „tekst”NSAttributedString
Stare pytanie, ale jeśli ktoś może użyć
UITextView
zamiast zamiastUILabel
, to jest łatwe. Standardowe adresy URL, numery telefonów itp. Zostaną automatycznie wykryte (i będą klikalne).Jednakże, jeśli trzeba wykrywanie niestandardową, to znaczy, jeśli chcesz być w stanie wywołać dowolną metodę niestandardową po kliknięciu przez użytkownika na danym słowem, trzeba użyć
NSAttributedStrings
zNSLinkAttributeName
atrybutów, które będą wskazywać na schemacie niestandardowy URL (w przeciwieństwie do domyślnie posiadający schemat http url). Ray Wenderlich omawia to tutajCytując kod z wyżej wspomnianego linku:
Aby wykryć kliknięcia linku, zaimplementuj to:
PS: Upewnij się, że
UITextView
ISselectable
.źródło
UIButtonTypeCustom to klikalna etykieta, jeśli nie ustawisz dla niej żadnych obrazów.
źródło
(Moja odpowiedź opiera się na doskonałej odpowiedzi @ NAlexN . Nie powielę tutaj jego szczegółowego wyjaśnienia każdego kroku).
Za najwygodniejsze i najprostsze uznałem dodanie obsługi UILabel z możliwością dotykania jako kategorii do UITapGestureRecognizer. (Nie musisz używać detektorów danych UITextView, jak sugerują niektóre odpowiedzi).
Dodaj następującą metodę do kategorii UITapGestureRecognizer:
Przykładowy kod
Oddzwonienie gestem
źródło
plainText.length
.UITapGestureRecognizer
. Oto kilka informacji na temat dodawania kategorii.UITextView
obsługuje detektory danych w OS 3.0, podczasUILabel
gdy nie.Jeśli włączysz detektory danych,
UITextView
a Twój tekst zawiera adresy URL, numery telefonów itp., Pojawią się one jako linki.źródło
hashtag://
lub coś, a następnie użyj go,textView(_:shouldInteractWith:in:interaction:)
aby go wykryć. Zobacz odpowiedź poniżej: stackoverflow.com/a/34014655/1161906Tłumaczenie rozszerzenia @ samwize na Swift 4:
Aby skonfigurować rozpoznawanie (po pokolorowaniu tekstu i innych rzeczy):
... następnie rozpoznawanie gestów:
źródło
didTapAttributedTextInLabel
potrzebujeNSRange
argumentu, alerangeTerms
zwraca coś innego. Również w Swift 4handleTapOnLabel
należy zaznaczyć tę funkcję@objc
Jak wspomniałem w tym poście , oto lekka biblioteka, którą stworzyłem specjalnie dla linków w UILabel FRHyperLabel .
Aby osiągnąć taki efekt:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque Quis blandit eros, sit amet vehicula Justo. Nam w urna neque. Maecenas ac sem eu sem porta dictum nec vel tellus.
użyj kodu:
źródło
Utworzyłem podklasę UILabel o nazwie ResponsiveLabel opartą na interfejsie API textkit wprowadzonym w iOS 7. Korzysta z tego samego podejścia sugerowanego przez NAlexN . Zapewnia elastyczność w określaniu wzorca do przeszukiwania w tekście. Można określić style, które zostaną zastosowane do tych wzorów, a także działania, które zostaną wykonane po stuknięciu wzorów.
Jeśli chcesz, aby ciąg był klikalny, możesz to zrobić w ten sposób. Ten kod stosuje atrybuty do każdego wystąpienia ciągu „tekst”.
źródło
Pracowałem w Swift 3, wklejając tutaj cały kod
źródło
Oto przykładowy kod do hiperłącza UILabel: Źródło: http://sickprogrammersarea.blogspot.in/2014/03/adding-links-to-uilabel.html
źródło
Oto szybka wersja odpowiedzi NAlexN.
Następnie możesz utworzyć instancję tej klasy w swojej
viewDidLoad
metodzie w następujący sposób:Lepiej mieć niestandardowy atrybut do użycia, gdy postać jest stukana. Teraz jest
NSLinkAttributeName
, ale może być czymkolwiek i możesz użyć tej wartości do innych celów niż otwieranie adresu URL, możesz wykonać dowolną akcję niestandardową.źródło
Trudno mi było sobie z tym poradzić ... UILabel z linkami do przypisanego tekstu ... to tylko ból głowy, więc skończyło się na ZSWTappableLabel .
źródło
Podobnie jak w poprzedniej odpowiedzi, UITextView jest w stanie obsłużyć linki. Można to łatwo rozszerzyć, sprawiając, że inne części tekstu działają jako łącza. Biblioteka AttributeTextView jest podklasą UITextView, która bardzo ułatwia ich obsługę. Aby uzyskać więcej informacji, zobacz: https://github.com/evermeer/AttributTextView
Możesz sprawić, by jakakolwiek część tekstu współdziałała w ten sposób (gdzie textView1 to IBOutlet UITextView):
Do obsługi hashtagów i wzmianek możesz użyć takiego kodu:
źródło
Rozszerzam odpowiedź @ samwize na obsługę wieloliniowego UILabel i podaję przykład użycia UIButton
źródło
Śledzę tę wersję,
Swift 4:
Przykład połączenia:
źródło
Znalazłem inne rozwiązanie:
Znajduję sposób na wykrycie linku w tekście HTML, który znajdziesz w Internecie, przekształcając go w nsattributeString za pomocą:
Moja metoda pozwala wykryć hiperłącze bez konieczności ich określania.
najpierw utworzysz rozszerzenie tapgesturerecognizer:
}
następnie w widoku kontrolera utworzyłeś listę adresów URL i zakresów do przechowywania wszystkich linków i zakresu, który zawiera tekst atrybutu:
aby znaleźć adres URL i URLRange, możesz użyć:
następnie wdrażasz uchwyt uchwytu:
i zaczynamy!
Mam nadzieję, że to rozwiązanie Ci się spodoba. Pomóż mi.
źródło
Aby uzyskać w pełni niestandardowe łącza, musisz użyć UIWebView - możesz przechwytywać połączenia, dzięki czemu możesz przejść do innej części aplikacji po naciśnięciu łącza.
źródło
Oto rozwijana kategoria Cel-C, która umożliwia klikalne łącza w istniejących
UILabel.attributedText
ciągach, wykorzystując istniejącyNSLinkAttributeName
atrybut.Byłoby to nieco bardziej przejrzyste dzięki podklasie UILabel (tj. Żadnemu bałaganowi objc_getAssociatedObject), ale jeśli jesteś podobny do mnie, wolisz unikać tworzenia niepotrzebnych podklas (stron trzecich), aby dodać dodatkową funkcję do istniejących klas UIKit. Ma to również tę zaletę, że dodaje klikalne linki do każdego istniejącego UILabel, np. Istniejącego
UITableViewCells
!Próbowałem uczynić go tak minimalnie inwazyjnym, jak to możliwe, używając istniejących
NSLinkAttributeName
atrybutów dostępnych już w NSAttributString. Jest to więc proste:Zasadniczo działa poprzez dodanie a
UIGestureRecognizer
do twojego UILabel. Ciężka praca jest wykonywana w celu zmianygestureRecognizerShouldBegin:
układu ciągu atrybutuText, aby dowiedzieć się, który znak został dotknięty. Jeśli ten znak był częścią NSLinkAttributeName, następnie gestRecognizer zostanie następnie uruchomiony, pobierz odpowiedni adres URL (z wartości NSLinkAttributeName) i otwórz łącze zgodnie ze zwykłym[UIApplication.sharedApplication openURL:url]
procesem.Uwaga - robiąc to wszystko
gestureRecognizerShouldBegin:
, jeśli nie stukniesz linku w etykiecie, zdarzenie zostanie przekazane. Na przykład Twój UITableViewCell będzie przechwytywał stuknięcia linków, ale poza tym zachowuje się normalnie (zaznacz komórkę, odznacz, przewiń, ...).Umieściłem to tutaj w repozytorium GitHub . Zaadaptowano z pisma SO Kai Burghardta tutaj .
źródło
Utwórz klasę za pomocą następujących plików .h i .m. W pliku .m znajduje się następująca funkcja
Wewnątrz tej funkcji sprawdzimy zakresy podciągów, dla których musimy podać akcje. Użyj swojej logiki, aby ustawić zakresy.
Poniżej znajduje się zastosowanie podklasy
poniżej znajduje się plik .h
poniżej znajduje się plik .m
źródło
Zdecydowanie polecam korzystanie z biblioteki, która automatycznie wykrywa adresy URL w tekście i konwertuje je na linki. Próbować:
Oba są na licencji MIT.
źródło
na podstawie odpowiedzi Charlesa Gamble, tego użyłem (usunąłem niektóre wiersze, które mnie pomieszały i dałem zły indeks):
źródło
Rozwijane rozwiązanie jako kategoria
UILabel
(zakłada to, że używaszUILabel
przypisanego ciągu z pewnymiNSLinkAttributeName
atrybutami):źródło
Oto implementacja Swift, która jest tak minimalna, jak to możliwe, która obejmuje również informacje dotykowe. Ostrzeżenia:
"\u{a0}"
).link
kluczy.
źródło
Ta ogólna metoda też działa!
Możesz wywołać metodę za pomocą
źródło
UITapGestureRecognizer
pochodzi? Czy to jest ujście? Właściwość, którą konfigurujeszTutaj jest moja odpowiedź na podstawie @Luca Davanzo za odpowiedź , przesłonić
touchesBegan
zdarzenie zamiast geście kranu:źródło
TAGI # Swift2.0
Inspiruję się - doskonale - odpowiedzią @ NAlexN i postanawiam napisać samodzielnie opakowanie UILabel.
Próbowałem też TTTAttributLabel, ale nie mogę sprawić, żeby działało .
Mam nadzieję, że docenisz ten kod, wszelkie sugestie są mile widziane!
źródło
0
przyczynę, któralocationOfTouchInTextContainer.x
była ujemna. Próbuję użyćlet indexOfCharacter = layoutManager.glyphIndex(for: locationOfTouch, in: textContainer)
zamiast tego i działa dobrze.źródło
Zmodyfikowano kod @timbroder, aby poprawnie obsługiwał wiele linii dla swift4.2
Kod UILabel
Kod rozpoznający kran
źródło
Jest to implementacja Xamarin.iOS c # oparta na odpowiedzi Kedara .
Implementacja MyClickableTextViewWithCustomUrlScheme z
ShouldInteractWithUrl
przesłonięciem:Przekształcony kod celu C w c # staje się:
Pamiętaj, aby ustawić opcję Editable = false i Selectable = true, aby móc kliknąć link.
Również ScrollEnabled = true pozwala widokowi tekstowemu odpowiednio dopasować jego wysokość.
źródło