Próbuję zbudować ekran wprowadzania danych dla iPhone'a. Na ekranie znajduje się wiele pól wejściowych. Większość z nich u góry ekranu, ale dwa pola u dołu. Kiedy użytkownik spróbuje edytować tekst na dole ekranu, klawiatura wyskoczy i zakryje ekran. Znalazłem proste rozwiązanie, aby przesunąć ekran w górę, gdy tak się dzieje, ale w rezultacie ekran zawsze przesuwa się w górę, a pola u góry ekranu przesuwają się poza zasięg, gdy użytkownik próbuje je edytować.
Czy istnieje sposób, aby ekran przesuwał się tylko wtedy, gdy edytowane są dolne pola?
Użyłem tego kodu, który znalazłem tutaj :
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 150
}
Odpowiedzi:
Twój problem jest dobrze wyjaśniony w tym dokumencie przez firmę Apple . Przykładowy kod na tej stronie (at
Listing 4-1
) robi dokładnie to, czego potrzebujesz, przewinie widok tylko wtedy, gdy bieżąca edycja powinna znajdować się pod klawiaturą. Wystarczy umieścić potrzebne elementy sterujące w widoku scrollViiew. Jedynym problemem jest to, że to jest Objective-C i myślę, że potrzebujesz go w Swift ... więc ... tutaj:Zadeklaruj zmienną
następnie dodaj te metody
Pamiętaj, aby zadeklarować ViewController jako
UITextFieldDelegate
i ustawić poprawnych delegatów w metodach inicjalizacji: np .:I pamiętaj, aby wywołać
registerForKeyboardNotifications
funkcję viewInit ideregisterFromKeyboardNotifications
przy wyjściu.Edycja / aktualizacja: składnia Swift 4.2
źródło
UIKeyboardFrameEndUserInfoKey
zamiastUIKeyboardFrameBeginUserInfoKey
, ponieważ ta ostatnia zwraca wysokość 0. I zmień najgorętszy punkt na dół, a nie początek.if let activeField = self.activeField { var point = activeField.frame.origin point.y += activeField.frame.size.height if (!aRect.contains(point)){ self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } }
textField's didBeginEditing
metoda nazywa się PO wywołaniukeyboardWillShow
metody. W rezultacieactiveField
zmienna jest nadal zerowa, co oznacza, że nie następuje automatyczne przewijanie. Moim rozwiązaniem było umieszczenieactiveField = textField
wywołania w metodzie textFieldshouldBeginEditing
. To rozwiązuje problem z kolejnością połączeń.Oto moje 2 centy:
Czy próbowałeś: https://github.com/hackiftekhar/IQKeyboardManager
Niezwykle łatwy w instalacji Swift lub Objective-C.
Oto jak to działa:
IQKeyboardManager (Swift): - IQKeyboardManagerSwift jest dostępny za pośrednictwem CocoaPods, aby go zainstalować, wystarczy dodać następujący wiersz do pliku Podfile: (# 236)
W AppDelegate.swift wystarczy zaimportować strukturę IQKeyboardManagerSwift i włączyć IQKeyboardManager.
I to wszystko. Łatwo!
źródło
IQKeyboardManager.shared.enable = true
Ten, który okazał się dla mnie idealny, to:
Możesz także zmienić wartości wysokości. Usuń instrukcję „if”, jeśli chcesz jej używać we wszystkich polach tekstowych.
Możesz nawet użyć tego dla wszystkich kontrolek, które wymagają wprowadzenia danych przez użytkownika, takich jak TextView.
źródło
Miałem podobny problem i znalazłem całkiem proste rozwiązanie bez używania scrollView i zamiast tego używając instrukcji if w metodach keyboardWillShow / Hide.
To było dla mnie dobre rozwiązanie, ponieważ miałem tylko dwa pola tekstowe.
Przesuwa cały widok w górę: tylko wtedy, gdy edytuje się określone pola tekstowe (bottomText)
Przesuwa cały widok w dół: tylko wtedy, gdy widok nie znajduje się w pierwotnej lokalizacji
źródło
Po prostu użyj tego rozszerzenia, aby przenieść dowolny UIView, gdy jest prezentowana klawiatura.
Następnie w swoim viewdidload powiąż swój widok z klawiaturą
źródło
Dlaczego nie zaimplementować tego w UITableViewController zamiast tego? Klawiatura nie ukryje żadnych pól tekstowych, gdy jest wyświetlana.
źródło
Swift 4 (** zaktualizowany ) z rozszerzeniem **
inViewDidLoad
dodaj następujące rozszerzenie
źródło
Używam SwiftLint, który miał kilka problemów z formatowaniem zaakceptowanej odpowiedzi. Konkretnie:
bez spacji przed dwukropkiem, bez rzutowania na siłę, preferuj UIEdgeInset (góra: etc ... zamiast UIEdgeInsetMake.
więc oto te aktualizacje dla Swift 3
źródło
Myślę, że ta klauzula jest błędna:
Chociaż początek activeField może znajdować się nad klawiaturą, maxY może nie ...
Utworzyłbym punkt „max” dla activeField i sprawdziłbym, czy jest na klawiaturze Rect.
źródło
Oto moja wersja po przeczytaniu dokumentacji dostarczonej przez Apple i poprzednich postów. Zauważyłem jedną rzecz, że textView nie był obsługiwany, gdy był zasłonięty przez klawiaturę. Niestety dokumentacja Apple nie będzie działać, ponieważ z jakiegoś powodu klawiatura jest wywoływana PO wywołaniu textViewDidBeginEditing. Poradziłem sobie z tym, wywołując metodę centralną, która sprawdza, czy klawiatura jest wyświetlana ORAZ czy edytowany jest textView lub textField. W ten sposób proces jest uruchamiany tylko wtedy, gdy istnieją OBIE warunki.
Inną kwestią związaną z textViews jest to, że ich wysokość może być taka, że klawiatura przycina dolną część textView i nie dostosowuje się, jeśli lewy górny punkt był widoczny. Tak więc kod, który napisałem, w rzeczywistości przyjmuje dolny lewy punkt dowolnego textView lub textField, do którego odwołuje się ekran i widzi, czy mieści się we współrzędnych wskazanych na ekranie prezentowanej klawiatury, co oznacza, że klawiatura pokrywa jej część.
Jeśli używasz kontrolera nawigacji, podklasa ustawia również automatyczne dostosowanie widoku przewijania dla wstawek na wartość false.
Przechodzi przez każdy textView i textField, aby ustawić delegatów do obsługi
Po prostu ustaw swoją klasę bazową na podklasę utworzoną tutaj, aby uzyskać wyniki.
źródło
Niesamowite odpowiedzi są już podane, ale jest to inny sposób radzenia sobie z tą sytuacją (używając Swift 3x ):
Najpierw wywołaj następującą metodę w
viewWillAppear()
Teraz weź jedno
IBOutlet
zUIView
najwyższych ograniczeń swojego wUIViewcontroller
ten sposób: (tutajUIView
jest podokreślenie,UIScrollView
które oznacza, że powinieneś miećUIScrollView
dla wszystkich swoichsubViews
)I kolejna zmienna, taka jak śledzenie i dodaj delegata, tj .
UITextFieldDelegate
:Po tym, oto magiczna część, po prostu wklej poniższy fragment :
Teraz ostatni fragment:
Nie zapomnij przypisać delegatów do wszystkich swoich
UITextField
plikówUIStoryboard
Powodzenia!
źródło
Składnia Swift 3:
to dobra metoda na uzyskanie tego, co chcesz możesz dodać warunki "jeśli" dla określonych pól tekstowych, ale ten typ działa dla wszystkich ... Mam nadzieję, że może być przydatny dla każdego
źródło
Przede wszystkim zadeklaruj zmienną identyfikującą Twoje aktywne pole UITextField.
Krok 1:-
Tak jak
var activeTextField: UITextField
?Krok 2: - Następnie dodaj te dwie linie w viewDidLoad.
Krok 3:-
Teraz zdefiniuj te dwie metody w swojej klasie kontrolera.
źródło
Utwórz var uitextfield
W Twoim widoku załadowano
Poznaj kliknięte pole tekstowe. prawdopodobnie masz pola tekstowe na całym ekranie.
Sprawdź, czy klawiatura zakrywa pole tekstowe, czy nie.
Wróć, aby zamknąć klawiaturę
UPDATE: NSNotification.Name.UIKeyboardWillShow i NSNotification.Name.UIKeyboardWillHide zmieniają nazwy odpowiednio na UIResponder.keyboardWillShowNotification i UIResponder.keyboardWillHideNotification.
źródło
Swift : Możesz to zrobić, sprawdzając, które pole textField jest prezentowane.
źródło
Ten kod przesuwa w górę pole tekstowe, które edytujesz, abyś mógł je wyświetlić w Swift 3 dla tej odpowiedzi, musisz również ustawić swój widok jako UITextFieldDelegate:
A potem w widoku DidLoad:
Które wywołania (widok zewnętrznyDidLoad):
źródło
Szybki 3
źródło
Przyjęta odpowiedź jest prawie idealna. Ale muszę użyć
UIKeyboardFrameEndUserInfoKey
zamiast,UIKeyboardFrameBeginUserInfoKey,
ponieważ te ostatnie zwracają wysokość klawisza 0. I zmienić najgorętszy punkt na dół, a nie początek.źródło
Swift 4 Zaktualizowałem moje rozwiązanie
z animacją ograniczeń na klawiaturze pokaż / ukryj, ciesz się.
źródło
Szybki 4
Możesz łatwo poruszać się w górę iw dół za
UITextField
pomocą klawiatury z animacjąźródło
Swift 4.2
Moje rozwiązanie wyśrodkuje (w pionie) widok na a,
UITextField
jeśli jego pozycja znajduje się pod klawiaturą.Krok 1: Utwórz nowy plik Swift i
UIViewWithKeyboard
klasę kopiuj-wklej .Krok 2: W programie Interface Builder ustaw go jako klasę niestandardową dla swoich najlepszych
UIView
.źródło
Przepisany na szybkie 4.2
W ViewDidLoad ...
Pozostałe funkcje
źródło
„Zapomniałem wspomnieć, że jestem nowy w Swift :( Jaka byłaby poprawna składnia, aby to sprawdzić? (Jak uzyskać nazwę pola w tej funkcji?)”
Dobrze . Najpierw potwierdź protokół UITextFieldDelegate
Następnie zaimplementuj funkcję
Należy pamiętać, że właściwym podejściem jest użycie widoku przewijania i umieszczenie widoku, który powinien być przesunięty w górę / w dół wewnątrz widoku przewijania i odpowiednia obsługa zdarzeń klawiatury
źródło
Dla Swift 4.2
Ten kod pozwoli ci kontrolować moment osi Y ramki dla określonego rozmiaru ekranu urządzenia.
PS: ten kod nie przesunie inteligentnie ramki w oparciu o lokalizację TextField.
Utwórz rozszerzenie dla UIDevice
Dodaj NotificationObserver na viewDidLoad
Selektor
źródło