Tworzę aplikację, która używa UITextView
. Teraz chcę, aby widok tekstu miał symbol zastępczy podobny do tego, który można ustawić dla pola tekstowego. Jak byś to zrobił za pomocą Swift?
ios
swift
uitextview
placeholder
StevenR
źródło
źródło
Odpowiedzi:
Zaktualizowano dla Swift 4
UITextView
nie ma z natury właściwości zastępczej, więc musisz programowo tworzyć i manipulować jedną z nich za pomocąUITextViewDelegate
metod. Zalecam użycie rozwiązania nr 1 lub nr 2 poniżej, w zależności od pożądanego zachowania.Uwaga: W przypadku obu rozwiązań dodaj
UITextViewDelegate
do klasy i skonfigurujtextView.delegate = self
użycie metod delegowania widoku tekstowego.Rozwiązanie nr 1 - Jeśli chcesz, aby symbol zastępczy zniknął, gdy tylko użytkownik wybierze widok tekstowy:
Najpierw ustaw,
UITextView
aby zawierał tekst zastępczy i ustaw go na jasnoszary kolor, aby naśladować wyglądUITextField
tekstu zastępczego. Zrób toviewDidLoad
albo w trakcie tworzenia widoku tekstu, albo po jego utworzeniu.Następnie, gdy użytkownik zaczyna edytować widok tekstu, jeśli widok tekstu zawiera symbol zastępczy (tj. Jeśli jego kolor jest jasnoszary), wyczyść tekst zastępczy i ustaw kolor tekstu na czarny, aby uwzględnić wpis użytkownika.
Następnie, gdy użytkownik zakończy edycję widoku tekstu i zrezygnował z pierwszej odpowiedzi, jeśli widok tekstu jest pusty, zresetuj jego symbol zastępczy, ponownie dodając tekst zastępczy i ustawiając jego kolor na jasnoszary.
Rozwiązanie nr 2 - Jeśli chcesz, aby symbol zastępczy wyświetlał się zawsze, gdy widok tekstu jest pusty, nawet jeśli widok tekstu jest zaznaczony:
Najpierw ustaw symbol zastępczy w
viewDidLoad
:(Uwaga: ponieważ OP chciał, aby widok tekstowy był zaznaczony, gdy tylko widok się załaduje, włączyłem zaznaczenie widoku tekstowego do powyższego kodu. Jeśli nie jest to pożądane zachowanie i nie chcesz, aby widok tekstowy był wybrany po załadowaniu widoku, usuń dwa ostatnie wiersze z powyższego fragmentu kodu).
Następnie skorzystaj z
shouldChangeTextInRange
UITextViewDelegate
metody:A także zaimplementuj,
textViewDidChangeSelection
aby uniemożliwić użytkownikowi zmianę pozycji kursora, gdy symbol zastępczy jest widoczny. (Uwaga:textViewDidChangeSelection
jest wywoływany przed załadowaniem widoku, więc sprawdź kolor widoku tekstu tylko wtedy, gdy okno jest widoczne):źródło
yourTextField.delegate = self
. Jeśli nie to zrobić,textViewDidBeginEditing
atextViewDidEndEditing
funkcje nie będą działać.Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
.let currentText = textView.text as NSString?
. Przekształćlet updatedText =
linię wlet updatedText = currentText?.replacingCharacters(in: range, with: text)
. Na koniec przekształćif updatedText.isEmpty
linię naif (updatedText?.isEmpty)! {
. To powinno wystarczyć!textView.selectedTextRange
od wewnątrzfunc textViewDidChangeSelection(_ textView: UITextView)
powoduje nieskończoną pętlę ...Pływający symbol zastępczy
Umieszczenie etykiety zastępczej nad widokiem tekstu, ustawienie czcionki, koloru i zarządzanie widocznością symboli zastępczych poprzez śledzenie zmian w liczbie znaków w widoku tekstowym jest proste, bezpieczne i niezawodne.
Swift 3:
Swift 2: To samo, z wyjątkiem:
italicSystemFontOfSize(textView.font.pointSize)
,UIColor.lightGrayColor
źródło
Zdecydowanie zalecamy użycie biblioteki KMPlaceholderTextView . Bardzo prosty w użyciu.
źródło
Szybki:
Dodaj widok tekstu programowo lub za pomocą Konstruktora interfejsów, jeśli ostatni, utwórz ujście:
Dodaj delegata (UITextViewDelegate):
W metodzie viewDidLoad dodaj następujące informacje:
Teraz pozwól mi przedstawić magiczną część, dodaj tę funkcję:
Pamiętaj, że będzie to wykonywane za każdym razem, gdy rozpocznie się edycja, tam sprawdzimy warunki, aby poinformować stan, używając właściwości color. Ustawienie tekstu na
nil
Nie polecam. Zaraz potem ustawiamy żądany kolor tekstu, w tym przypadku czarny.Teraz dodaj też tę funkcję:
Pozwólcie mi nalegać, nie porównywać
nil
, już próbowałem i to nie zadziała. Następnie przywracamy wartości do stylu zastępczego i przywracamy kolor do koloru zastępczego, ponieważ jest to warunek wpisania siętextViewDidBeginEditing
.źródło
Użyj tego rozszerzenia jest to najlepszy sposób na ustawienie symbolu zastępczego w UITextView. Ale upewnij się, że dołączyłeś delegatów do TextView. Możesz ustawić Uchwyt miejsca w ten sposób: -
źródło
Dziwi mnie, że nikt o tym nie wspomniał
NSTextStorageDelegate
.UITextViewDelegate
metody będą uruchamiane tylko przez interakcję użytkownika, ale nie programowo. Np. Kiedytext
programowo ustawisz właściwość widoku tekstowego , będziesz musiał sam ustawić widoczność elementu zastępczego, ponieważ metody delegowania nie zostaną wywołane.Jednak z
NSTextStorageDelegate
„stextStorage(_:didProcessEditing:range:changeInLength:)
metody, będziesz powiadamiany o wszelkich zmianach w tekście, nawet jeśli jest to zrobione programowo. Po prostu przypisz to w ten sposób:(W
UITextView
tej właściwości delegowania jestnil
domyślnie, więc nie wpłynie to na żadne domyślne zachowanie).W połączeniu z
UILabel
techniką @clearlight demonstruje, można łatwo owinąć całąUITextView
„splaceholder
wdrażania do rozszerzenia.Zauważ, że użycie prywatnej (zagnieżdżonej) klasy o nazwie
PlaceholderLabel
. W ogóle nie ma żadnej implementacji, ale zapewnia nam sposób na identyfikację etykiety zastępczej, która jest znacznie bardziej „szybka” niż użycietag
właściwości.Dzięki takiemu podejściu nadal możesz przypisać delegata
UITextView
komuś innemu.Nie musisz nawet zmieniać klas widoków tekstowych. Po prostu dodaj rozszerzenie (rozszerzenia), a będziesz mógł przypisać łańcuch zastępczy do każdego
UITextView
w swoim projekcie, nawet w Konstruktorze interfejsów.placeholderColor
Ze względu na przejrzystość pominąłem implementację właściwości, ale można ją zaimplementować tylko dla kilku kolejnych wierszy z podobną zmienną obliczoną doplaceholder
.źródło
textView.textStorage.delegate = self
to w kontrolerze widoku będzie wymagało od nas powiązania tego kontrolera widokuNSTextStorageDelegate
. To naprawdę wymaga?NSTextStorageDelegate
, a nie kontroler widoku.Zrobiłem to, używając dwóch różnych widoków tekstu:
Chodzi o to, że gdy użytkownik zacznie wpisywać rzeczy w widoku pierwszego planu, symbol zastępczy w tle znika (i pojawia się ponownie, jeśli użytkownik usunie wszystko). Zachowuje się więc dokładnie jak symbol zastępczy dla jednowierszowego pola tekstowego.
Oto kod, którego użyłem do tego. Zauważ, że descriptionField jest polem, w którym wpisuje się użytkownik, a descriptionPlaceholder znajduje się w tle.
źródło
W oparciu o kilka świetnych sugestii, które udało mi się już uzyskać, udało mi się stworzyć następującą lekką podklasę kompatybilną z Konstruktorem interfejsów
UITextView
, z której:UITextField
.text
.Wszelkie sugestie dotyczące ulepszeń są mile widziane, zwłaszcza jeśli istnieje jakiś sposób programowego pobrania koloru zastępczego iOS, zamiast kodowania go na stałe.
Swift v5:
źródło
Ustaw wartość w widoku obciążenia
źródło
Starałem się uczynić kod wygodny z Clearlight „s odpowiedź .
stosowanie
źródło
Jeszcze jedno rozwiązanie (Swift 3):
wynik
źródło
Proste i szybkie rozwiązanie, które działa dla mnie to:
źródło
Oto, czego używam do tej pracy.
Wiem, że istnieje kilka podejść podobnych do tego, ale korzyści z tego są następujące:
źródło
Szybki 3.2
Najpierw, gdy użytkownik rozpocznie edycję wywołania textViewDidBeginEditing, a następnie sprawdź, czy kolor szarego tekstu oznacza, że użytkownik nic nie napisał, a następnie ustaw go jako zero i zmień kolor na czarny w celu wysyłania SMS-ów.
Gdy użytkownik kończy edycję textViewDidEndEditing, należy zadzwonić i sprawdzić, czy użytkownik nic nie pisze w widoku tekstu, a następnie tekst jest ustawiony na szary kolor z tekstem „PlaceHolder”
źródło
Oto mój sposób rozwiązania tego problemu ( Swift 4 ):
Pomysł polegał na stworzeniu najprostszego możliwego rozwiązania, które pozwala na użycie symboli zastępczych o różnych kolorach, zmienia rozmiar na symbole zastępcze, nie zastępuje
delegate
tymczasem wszystkichUITextView
funkcji działających zgodnie z oczekiwaniami.źródło
Nie wiem, dlaczego ludzie tak bardzo komplikują ten problem ... To dość proste i proste. Oto podklasa UITextView, która zapewnia żądaną funkcjonalność.
źródło
To jest moje gotowe do użycia rozwiązanie, jeśli pracujesz z wieloma widokami tekstu
źródło
Swift 3.1
To rozszerzenie działało dla mnie dobrze: https://github.com/devxoul/UITextView-Placeholder
Oto fragment kodu:
Zainstaluj przez pod:
Zaimportuj go do swojej klasy
I dodaj
placeholder
właściwość do już utworzonegoUITextView
To wszystko ... Oto jak to wygląda (trzecie pole to
UITextView
)źródło
W przeciwieństwie do prawie każdą odpowiedź w tym poście,
UITextView
nie posiada właściwości zastępczy. Z przyczyn poza moim zrozumieniem jest on ujawniony tylko w IB, jako taki:Więc jeśli używasz scenorysów, a statyczny symbol zastępczy wystarczy, po prostu ustaw właściwość na inspektorze.
Możesz także ustawić tę właściwość w kodzie w następujący sposób:
Jest pochmurno ze względu na pogodę, do której można uzyskać dostęp za pośrednictwem prywatnego interfejsu API, ponieważ nieruchomość jest odsłonięta.
Nie próbowałem przesłać tej metody. Wkrótce jednak przedstawię ten sposób i odpowiednio zaktualizuję tę odpowiedź.
AKTUALIZACJA:
Wysłałem ten kod w wielu wersjach bez problemów od Apple.
AKTUALIZACJA: Działa to tylko w Xcode przed 11.2
źródło
UITextField
NIEUITextView
czytaj uważniej pytań / odpowiedzi.W iOS nie ma takiej właściwości do dodania symbolu zastępczego bezpośrednio w TextView, ale można dodać etykietę i pokazać / ukryć zmianę w textView. SWIFT 2.0 i pamiętaj o wdrożeniu textviewdelegate
źródło
Swift - napisałem klasę, która odziedziczyła UITextView i dodałem UILabel jako widok podrzędny, aby działał jako symbol zastępczy.
źródło
Podoba mi się rozwiązanie @ nerdist. Na tej podstawie stworzyłem rozszerzenie do
UITextView
:Na przykład w klasie ViewController używam tego:
Symbol zastępczy w UITextview!
AKTUALIZACJA :
W przypadku zmiany tekstu widoku tekstu w kodzie pamiętaj o wywołaniu metody updateVisibitly w celu ukrycia symbolu zastępczego:
Aby zapobiec dodawaniu symbolu zastępczego więcej niż jeden raz,
add()
dodawana jest funkcja prywatnaextension
.źródło
W swift2.2:
}
W swift3:
klasa CustomTextView: UITextView {
}
Szybko napisałem klasę. Musisz zaimportować tę klasę, gdy zajdzie taka potrzeba.
źródło
Nie mogę dodać komentarza z powodu reputacji. dodaj jeszcze jedną potrzebę delegata w odpowiedzi na @clearlight.
jest potrzeba
ponieważ
textViewDidChange
nie jest wywoływany za pierwszym razemźródło
nie, nie ma żadnego elementu zastępczego dostępnego do przeglądania tekstu. musisz umieścić etykietę nad nim, gdy użytkownik wejdzie w widok tekstu, a następnie ukryj go lub ustaw wartość domyślną, gdy użytkownik wejdzie, usuń wszystkie wartości.
źródło
źródło
Musiałem wysłać kolejkę, aby mój tekst zastępczy pojawił się ponownie po zakończeniu edycji.
źródło
Szybki:
Dodaj swój
TextView
@IBOutlet
:W
viewWillAppear
metodzie dodaj następujące:Dodaj
Delegate
rozszerzenie Korzystanie (UITextViewDelegate):źródło
Nasze rozwiązanie pozwala uniknąć kumulacji właściwości
UITextView
text
itextColor
, co jest przydatne, jeśli utrzymujesz licznik postaci.To proste:
1) Utwórz manekina
UITextView
w Storyboard o takich samych właściwościach jak masterUITextView
. Przypisz tekst zastępczy do tekstu zastępczego.2) Dopasuj górną, lewą i prawą krawędź obu
UITextViews.
3) Umieść manekina za mistrzem.
4) Zastąp funkcję
textViewDidChange(textView:)
delegowania mastera i pokaż manekina, jeśli master ma 0 znaków. W przeciwnym razie pokaż mistrza.Zakłada się, że oba
UITextViews
mają przezroczyste tło. Jeśli nie, umieść manekina na górze, gdy jest 0 znaków, i wciśnij go, gdy jest> 0 znaków. Będziesz także musiał zamienić respondentów, aby upewnić się, że kursor podąża w prawoUITextView
.źródło
Swift 4, 4.2 i 5
źródło