Miałem też duży problem z UIScrollViewkomponowaniem wielu UITextFields, z których jeden lub więcej z nich zostałoby zasłoniętych przez klawiaturę podczas edytowania.
Oto kilka rzeczy do rozważenia, jeśli twoje UIScrollViewprzewijanie nie jest prawidłowe.
1) Upewnij się, że rozmiar contentSize jest większy niż UIScrollViewrozmiar ramki. Można zrozumieć, UIScrollViewsże UIScrollViewjest to okno do oglądania treści zdefiniowanej w contentSize. Gdy więc, UIScrollviewaby przewijać w dowolnym miejscu, contentSize musi być większy niż UIScrollView. W przeciwnym razie przewijanie nie jest wymagane, ponieważ wszystko zdefiniowane w contentSize jest już widoczne. BTW, domyślna treść Rozmiar = CGSizeZero.
2) Teraz, gdy rozumiesz, że UIScrollViewtak naprawdę jest to okno na twoją „treść”, sposobem na upewnienie się, że klawiatura nie zasłania twojego UIScrollView's„okna” oglądania, będzie zmiana rozmiaru UIScrollViewtak, aby gdy klawiatura była obecna, masz UIScrollViewokno rozmiar tylko do oryginalnej UIScrollViewramki. rozmiar. wysokość minus wysokość klawiatury. Zapewni to, że twoje okno jest tylko tym małym widocznym obszarem.
3) Oto haczyk: kiedy po raz pierwszy to zaimplementowałem, pomyślałem, że będę musiał pobrać CGRectedytowane pole tekstowe i wywołać UIScrollView'smetodę scrollRecToVisible. Zaimplementowałem UITextFieldDelegatemetodę textFieldDidBeginEditingza pomocą wywołania scrollRecToVisiblemetody To faktycznie zadziałało z dziwnym efektem ubocznym, że przewijanie zatrzasnęło się UITextFieldw pozycji. Najdłużej nie mogłem zrozumieć, co to było. Potem skomentowałem textFieldDidBeginEditingmetodę Delegata i wszystko działa !! (???). Jak się okazało, wierzę, że UIScrollViewfaktycznie niejawnie przenosi aktualnie edytowane UITextFielddo widocznego okna. Moja implementacja UITextFieldDelegatemetody i późniejsze wywołanie jej scrollRecToVisiblebyło zbędne i było przyczyną dziwnego efektu ubocznego.
Oto kroki, które należy wykonać, aby poprawnie przewinąć urządzenie UITextFieldw odpowiednie UIScrollViewmiejsce, gdy pojawi się klawiatura.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
CGSize scrollContentSize = CGSizeMake(320, 345);
self.scrollView.contentSize = scrollContentSize;
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the scrollview
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height += (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
- (void)keyboardWillShow:(NSNotification *)n
{
// This is an ivar I'm using to ensure that we do not do the frame size adjustment on the `UIScrollView` if the keyboard is already shown. This can happen if the user, after fixing editing a `UITextField`, scrolls the resized `UIScrollView` to another `UITextField` and attempts to edit the next `UITextField`. If we were to resize the `UIScrollView` again, it would be disastrous. NOTE: The keyboard notification will fire even when the keyboard is already shown.
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- Zarejestruj się, aby otrzymywać powiadomienia na klawiaturze pod adresem
viewDidLoad
- Wyrejestruj, aby uzyskać informacje na temat klawiatury na
viewDidUnload
- Upewnij się, że
contentSizejest ustawiony i większy niż twój UIScrollViewwviewDidLoad
- Kurczyć
UIScrollView gdy klawiatura jest obecny
- Powrócić
UIScrollView gdy klawiatura odchodzi.
- Użyj ivar wykryć, czy klawiatura jest już wyświetlany na ekranie od powiadomienia klawiaturowe są wysyłane za każdym razem, gdy
UITextFieldjest kartach nawet jeśli klawiatura jest już obecny, aby uniknąć kurczeniaUIScrollView kiedy jest już skurczony
Jedną rzeczą do odnotowania jest to, że UIKeyboardWillShowNotificationuruchomi się nawet, gdy klawiatura jest już na ekranie, gdy tabulujesz inną UITextField. Zadbałem o to, używając ivara, aby uniknąć zmiany rozmiaru, UIScrollViewgdy klawiatura jest już na ekranie. Nieumyślna zmiana rozmiaru, UIScrollViewgdy klawiatura jest już dostępna, byłaby katastrofalna!
Mam nadzieję, że ten kod zaoszczędzi niektórym z was dużo bólu głowy.