Mam problem z kodem. Próbuję przesunąć UIScrollView
podczas edycji element, UITextField
który powinien być ukryty za pomocą klawiatury.
W tej chwili przesuwam główną ramkę, ponieważ nie wiem, jak „przewijać w górę” w kodzie. Zrobiłem więc trochę kodu, działa dobrze, ale kiedy edytuję pole UItext i przełączam się na inne UITextField
bez naciskania przycisku „powrót”, widok główny idzie aż za bardzo w górę.
Zrobiłem NSLog()
z moimi zmiennymi size, distance i textFieldRect.origin.y, jak widać poniżej. Kiedy umieszczam dwa UITextField
w tym samym miejscu (początek y) i robię ten konkretny 'przełącznik' (bez naciśnięcia klawisza Return), otrzymuję te same liczby, podczas gdy mój kod działał dobrze przy pierwszej UITextField
edycji, ale nie przy drugiej edycji.
Sprawdź to:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
{
int size;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
size = textFieldRect.origin.y + textFieldRect.size.height;
if (change == FALSE)
{
size = size - distance;
}
if (size < PORTRAIT_KEYBOARD_HEIGHT)
{
distance = 0;
}
else if (size > PORTRAIT_KEYBOARD_HEIGHT)
{
distance = size - PORTRAIT_KEYBOARD_HEIGHT + 5; // +5 px for more visibility
}
NSLog(@"origin %f", textFieldRect.origin.y);
NSLog(@"size %d", size);
NSLog(@"distance %d", distance);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
change = FALSE;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
change = TRUE;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
Jakieś pomysły ?
źródło
activeField.frame
na względną ramkę, ponieważactiveField
nie musi być bezpośrednim dzieckiemself.view
. Zaktualizowany kod powinien wyglądaćCGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; CGRect relativeFieldFrame = [activeField convertRect:activeField.frame toView:self.view]; if (!CGRectContainsPoint(aRect, relativeFieldFrame.origin) ) { CGPoint scrollPoint = CGPointMake(0.0, relativeFieldFrame.origin.y-kbSize.height); [self.mainView.scrollView setContentOffset:scrollPoint animated:YES]; }
UIKeyboardFrameEndUserInfoKey
klucza na iOS 11, ponieważUIKeyboardFrameBeginUserInfoKey
często podawał mi wysokość zero.Właśnie zaimplementowałem to w Swift 2.0 dla iOS9 na Xcode 7 (beta 6), tutaj działa dobrze.
Edytowane dla Swift 3
Wygląda na to, że musisz tylko ustawić,
contentInset
awscrollIndicatorInset
Swift 3 przewijanie / przesunięcie zawartości odbywa się automatycznie.źródło
Wszystkie odpowiedzi wydają się zapominać o możliwościach krajobrazu. Jeśli chcesz, aby to działało, gdy urządzenie jest obrócone do widoku poziomego, napotkasz problemy.
Sztuczka polega na tym, że chociaż widok jest świadomy orientacji, klawiatura nie. Oznacza to, że w trybie Landscape szerokość klawiatury jest w rzeczywistości jego wysokością i odwrotnie.
Aby zmodyfikować zalecany przez Apple sposób zmiany wstawek zawartości i uzyskać obsługę orientacji poziomej, polecam skorzystanie z:
Część, na którą należy zwrócić uwagę, jest następująca:
To, co robi, to wykrywa orientację, w jakiej znajduje się urządzenie. Jeśli jest ustawiony poziomo, „zamienia” wartości szerokości i wysokości zmiennej keyboardSize, aby upewnić się, że w każdej orientacji używane są prawidłowe wartości.
źródło
Rozwiązanie Swift 4 :
źródło
UIKeyboardFrameBeginUserInfoKey
naUIKeyboardFrameEndUserInfoKey
UIKeyboardWillShow
,UIKeyboardWillHide
IUIKeyboardFrameBeginUserInfoKey
został przemianowany naUIResponder.keyboardWillShowNotification
,UIResponder.keyboardWillHideNotification
, iUIResponder.keyboardFrameBeginUserInfoKey
.Do tego nie potrzeba dużo kodowania, jest to bardzo proste, jak poniżej: -
wszystkie twoje pliki tekstowe w UIScrollview ze stalówki jak ten obraz: -
YourViewController.h
podłącz IBOutlet z nib, a także Połącz każdego delegata delegata UItextfiled i scrollview z NIB
UWAGA jeśli delegat z tekstem nie jest podłączony, żadna metoda nie działa, upewnij się, że wszystkie iBOulate i delegat są prawidłowo podłączone
źródło
Rekomendacja Apple przekodowana w Swift + Using UIScrollView with Auto Layout w iOS (na podstawie poniższych linków: link 1 , link 2 , link 3 ):
źródło
Jedyną rzeczą, którą zaktualizowałbym w kodzie Apple, jest metoda keyboardWillBeHidden:, zapewniająca płynne przejście.
źródło
Oto odpowiedź zgodna ze Swift 3 , która będzie działać również z kontrolerami widoku w kontrolerze nawigacji - ponieważ zmienią one
contentInset.top
właściwość widoków przewijania .źródło
Szybkie rozwiązanie 4.2 , które uwzględnia możliwe wysokości UIToolbar i UITabBar.
A jeśli celujesz w <iOS 9, musisz w pewnym momencie wyrejestrować obserwatora (dzięki Joe )
źródło
Zauważyłem, że powyższe odpowiedzi są nieaktualne. Nie jest też doskonały podczas przewijania.
Oto szybka wersja.
Przewinie się tuż pod textField, bez wolnego miejsca. I przywróci stan, w jakim się pojawił.
źródło
To jest to, czego używałem. To proste i działa dobrze.
Użyj
UITextField
wywołania pełnomocnika,textFieldDidBeginEditing:
aby przesunąć widok w górę, a także dodaj obserwatora powiadomień, aby przywrócić normalny widok po ukryciu klawiatury:źródło
To jest ostateczny kod z ulepszeniami w Swift
źródło
Jednym z najłatwiejszych rozwiązań jest użycie następującego protokołu:
Jeśli chcesz korzystać z tego protokołu, wystarczy go dostosować i przypisać widok przewijania w kontrolerze w następujący sposób:
źródło
Zrobiłbym to w ten sposób. Jest to dużo kodu, ale zapewnia, że aktualnie zaznaczone pole textField jest wyśrodkowane w pionie w „dostępnej przestrzeni”:
Zauważ, że
- (IBAction)textFieldGotFocus:
akcja jest podłączona do każdegoDidBeginEditing
stanu textField .Byłoby też trochę lepiej, aby uzyskać czas trwania animacji z powiadomienia z klawiatury i użyć go do animacji scrollview zamiast stałej wartości, ale pozwól mi, to mi wystarczyło;)
źródło
Użyj następującego rozszerzenia, jeśli nie chcesz obliczać za dużo:
A może chcesz, aby Twoje pole UITextField było zawsze widoczne:
źródło
Wypróbuj ten kod w Swift 3:
źródło
Rozwiązanie Swift 5 w oparciu o powyższe rozwiązanie Masa - zmiany w stosunku do niego:
keyboardFrameEndUserInfoKey
zamiastkeyboardFrameBeginUserInfoKey
, ponieważkeyboardFrameBeginUserInfoKey
can na pierwszym show zwraca inną wartość, jak opisano na przykład tutaj: wysokość klawiatury zmienia się, gdy się pojawiaUIResponder.keyboardWillShowNotification
/UIResponder.keyboardWillHideNotification
zamiastNSNotification.Name.UIKeyboardDidShow
/NSNotification.Name.UIKeyboardDidHide
Kod:
źródło
W rzeczywistości nie potrzebujesz do tego UIScrollView. Użyłem tego kodu i działa u mnie:
źródło
Można przewijać za pomocą właściwości
contentOffset
wUIScrollView
, na przykład,Istnieje również metoda przewijania animowanego.
Jeśli chodzi o powód, dla którego druga edycja nie przewija się poprawnie, może to być spowodowane tym, że wydaje się, że nowa klawiatura pojawi się za każdym razem, gdy rozpocznie się edycja. Możesz spróbować sprawdzić, czy już dostosowałeś widoczną pozycję „klawiatury” (a także sprawdzić widoczność klawiatury w tej chwili przed jej przywróceniem).
Lepszym rozwiązaniem może być nasłuchiwanie powiadomień z klawiatury, np .:
źródło
Wiem, że to stare pytanie, ale pomyślałem, że może pomóc innym. Chciałem czegoś łatwiejszego do zaimplementowania dla kilku aplikacji, które miałem, więc stworzyłem na to zajęcia. Możesz go pobrać tutaj, jeśli chcesz: https://github.com/sdernley/iOSTextFieldHandler
Jest to tak proste, jak ustawienie wszystkich UITextFields, aby miały delegata siebie
A następnie dodaj to do kontrolera widoku z nazwą twojego scrollView i przycisku przesyłania
źródło
Oto moje rozwiązania, które działają (5 kroków)
Krok 1: Dodaj obserwatora, aby złapać, który UITEXTFIELD lub UITEXTVIEW ShoudBeginEditing (gdzie obiekt jest inicjowany lub ViewDidLoad.
Krok 2: Opublikuj powiadomienie, kiedy .. Powinien rozpocząć się edycja z OBJECT z UITEXTFIELD lub UITEXTVIEW
Krok 3: Metoda, która (wywołuje Step1) przypisuje bieżące UITEXTFIELD lub UITEXTVIEW
Krok 4: Dodaj obserwatora klawiatury UIKeyboardWillShowNotification (to samo miejsce co w kroku 1)
i metoda:
Krok 5: Dodaj obserwatora klawiatury UIKeyboardWillHideNotification (to samo miejsce co w kroku 1)
i metoda:
Pamiętaj o usuwaniu obserwatorów!
źródło
Skorzystałem z tej odpowiedzi dostarczonej przez Sudheer Palchuri https://stackoverflow.com/users/2873919/sudheer-palchuri https://stackoverflow.com/a/32583809/6193496
W ViewDidLoad zarejestruj powiadomienia:
Dodaj poniżej metody obserwatora, które wykonują automatyczne przewijanie po pojawieniu się klawiatury.
źródło
Moje rozwiązanie ma 4 kroki:
- Krok 1: funkcja nasłuchuje, gdy pojawia się klawiatura
- Krok 2: funkcja nasłuchuje, gdy klawiatura znika
- Krok 3: dodaj te funkcje do centrum powiadomień:
- Krok 4: usuń nasłuchiwanie, gdy kontroler widoku zniknie
źródło