Jak mogę wykryć jakiekolwiek zmiany tekstu w polu tekstowym? Metoda delegowania shouldChangeCharactersInRange
na coś działa, ale nie spełniła dokładnie mojej potrzeby. Ponieważ dopóki nie zwróci TAK, teksty textField nie są dostępne dla innych metod obserwatora.
np. w moim kodzie calculateAndUpdateTextFields
nie dostałem zaktualizowanego tekstu, użytkownik wpisał.
Jest ich sposobem na uzyskanie czegoś takiego jak textChanged
moduł obsługi zdarzeń Java.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
if (textField.tag == kTextFieldTagSubtotal
|| textField.tag == kTextFieldTagSubtotalDecimal
|| textField.tag == kTextFieldTagShipping
|| textField.tag == kTextFieldTagShippingDecimal)
{
[self calculateAndUpdateTextFields];
}
return YES;
}
Odpowiedzi:
Od właściwego sposobu zmiany tekstu uitextfield oddzwoń :
W celu C:
W Swift:
Można użyć tego i umieścić calculateAndUpdateTextFields jak twoje
selector
.źródło
NO
, co jest logiczne, ponieważ po powrocieNO
z tej metody w zasadzie mówisz, że tekst w polu nie powinien się zmieniać.textField.text = "Some new value";
. Czy istnieje sprytny sposób na złapanie tego?UITextFieldDelegate
że coś takiegofunc textField: UITextField, didChangeText text: String
zostałoby uwzględnione, ale ... (obrzuca facetów z Apple nieprzyzwoitym wyglądem)Odpowiedź XenElement jest natychmiastowa.
Powyższe można również wykonać w narzędziu do tworzenia interfejsów, klikając prawym przyciskiem myszy pole UITextField i przeciągając zdarzenie wysyłania „Edycja zmieniona” do jednostki podklasy.
źródło
aby ustawić detektor zdarzeń:
faktycznie słuchać:
źródło
Szybki:
Następnie zaimplementuj funkcję zwrotną:
źródło
Jak stwierdzono tutaj: Zdarzenie zmiany tekstu UITextField , wydaje się, że od iOS 6 (sprawdzone iOS 6.0 i 6.1) nie jest możliwe pełne wykrycie zmian w
UITextField
obiektach po prostu obserwującUITextFieldTextDidChangeNotification
.Wygląda na to, że śledzone są teraz tylko te zmiany wprowadzone bezpośrednio przez wbudowaną klawiaturę iOS. Oznacza to, że jeśli zmienisz
UITextField
obiekt tylko przez wywołanie czegoś takiego:myUITextField.text = @"any_text"
nie otrzymasz powiadomienia o żadnych zmianach.Nie wiem, czy to błąd, czy zamierzony. Wygląda na błąd, ponieważ nie znalazłem żadnego uzasadnionego wyjaśnienia w dokumentacji. Jest to również stwierdzone tutaj: Zdarzenie zmiany tekstu UITextField .
Moje „rozwiązanie” tego problemu polega na tym, że faktycznie wysyłam powiadomienie o każdej wprowadzonej przeze mnie zmianie
UITextField
(jeśli ta zmiana zostanie dokonana bez użycia wbudowanej klawiatury iOS). Coś takiego:W ten sposób masz 100% pewności, że otrzymasz takie samo powiadomienie po zmianie
.text
właściwości swojegoUITextField
obiektu, albo kiedy zaktualizujesz go „ręcznie” w kodzie, albo za pomocą wbudowanej klawiatury iOS.Należy wziąć pod uwagę, że ponieważ nie jest to udokumentowane zachowanie, takie podejście może prowadzić do otrzymania 2 powiadomień o tej samej zmianie w
UITextField
obiekcie. W zależności od potrzeb (co faktycznie robisz poUITextField.text
wprowadzeniu zmian) może to być dla Ciebie niedogodne.Nieco innym podejściem byłoby opublikowanie niestandardowego powiadomienia (to znaczy o niestandardowej nazwie innej niż
UITextFieldTextDidChangeNotification
), jeśli faktycznie chcesz wiedzieć, czy powiadomienie było twoje, czy „wykonane na iOS”.EDYTOWAĆ:
Właśnie znalazłem inne podejście, które moim zdaniem mogłoby być lepsze:
Dotyczy to funkcji Key-Value Observing (KVO) Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA ).
Zasadniczo rejestrujesz się jako obserwator nieruchomości, a jeśli ta właściwość się zmieni, zostaniesz o tym powiadomiony. „Zasada” jest dość podobna do tego
NSNotificationCenter
, jak działa, jest to główna zaleta, że to podejście działa automatycznie również od iOS 6 (bez żadnych specjalnych poprawek, takich jak konieczność ręcznego publikowania powiadomień).W naszym
UITextField
scenariuszu działa to dobrze, jeśli dodasz ten kod, na przykład do tego,UIViewController
który zawiera pole tekstowe:Podziękowania dla tej odpowiedzi dotyczącej zarządzania „kontekstem”: https://stackoverflow.com/a/12097161/2078512
Uwaga: Wydaje się, gdy jesteś w procesie edycji
UITextField
z wbudowaną klawiaturą iOS, „Tekst” własność pola tekstowego nie jest aktualizowany przy każdej nowej litery wpisane / usunięte. Zamiast tego obiekt pola tekstowego jest aktualizowany „jako całość” po rezygnacji ze statusu pierwszego pola odpowiadającego w polu tekstowym.źródło
Możemy łatwo to skonfigurować
Storyboard
, CTRL przeciągnij@IBAction
i zmień zdarzenie w następujący sposób:źródło
Tutaj w szybkiej wersji za to samo.
Dzięki
źródło
Rozwiązałem problem zmieniający zachowanie shouldChangeChractersInRange. Jeśli zwrócisz NIE, zmiany nie zostaną zastosowane wewnętrznie przez iOS, zamiast tego możesz zmienić je ręcznie i wykonać dowolne działania po zmianach.
źródło
Testowana wersja Swift:
Parametry wyjaśnione:
Następnie dodaj metodę utworzoną powyżej w
UIViewController
:źródło
Szybki 4
źródło
W przypadku Swift 3.0:
za pomocą klasy takiej jak:
źródło
Wersja Swift 3
I zobacz zmiany tutaj
Mam nadzieję, że to pomoże.
źródło
Powinieneś użyć powiadomienia, aby rozwiązać ten problem, ponieważ druga metoda nasłuchuje pola wprowadzania danych, a nie rzeczywistych danych wejściowych, szczególnie gdy używasz chińskiej metody wprowadzania danych. In viewDidload
następnie
}
w końcu uciekniesz, zrobisz.
źródło
Swift 3.1:
źródło
Wersja Swift 3:
Nie zapomnij ustawić delegata.
źródło
Z zamknięciem:
i za pomocą
źródło
KVO NIE działa w iOS dla kontroli: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html
Biorąc pod uwagę, że znasz widok tekstu, który chcesz obejrzeć:
Zrób to:
Uważaj jednak na to:
jest prawdopodobne, że chcesz zadzwonić tylko raz , więc nie dzwoń na przykład
layoutSubviews
trudno jest wiedzieć, kiedy najlepiej zadzwonić w trakcie procesu wychowawczego. Będzie to zależeć od twojej sytuacji. Niestety nie ma standardowego, zamkniętego rozwiązania
na przykład zwykle z pewnością nie możesz zadzwonić na
init
czas, ponieważ oczywiściewatchedTextView
może jeszcze nie istnieć.
Żadne z powiadomień nie jest wywoływane, gdy tekst jest zmieniany programowo .
To ogromna, odwieczna i głupia uciążliwość w inżynierii iOS.
Sterowanie po prostu nie - koniec historii - wywołuje powiadomienia, gdy właściwość .text jest programowo zmieniana.
Jest to niezwykle denerwujące, ponieważ - oczywiście - każda aplikacja, która kiedykolwiek wyprodukowała, ustawia tekst programowo, na przykład czyści pole po postach użytkownika itp.
Musisz podklasować widok tekstu (lub podobny element sterujący) w następujący sposób:
(Wskazówka - nie zapomnij, że super połączenie musi przyjść wcześniej !
Nie ma dostępnego rozwiązania, chyba że naprawisz kontrolę przez podklasowanie, jak pokazano powyżej. To jest jedyne rozwiązanie.
Pamiętaj, że powiadomienie
prowadzi do
być nazwanym.
( Nie
textViewDidChange
.)źródło
źródło
Jedną rzeczą jest to, że możesz mieć wiele pól UITextFields. Daj im tag, a następnie możesz włączyć tagi. Oto jak ustawić obserwatora w dowolnej klasie.
źródło
Wersja Swift 4
Korzystanie z obserwacji klucz-wartość Powiadamiaj obiekty o zmianach właściwości innych obiektów.
źródło