Miałem też duży problem z UIScrollView
komponowaniem 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 UIScrollView
przewijanie nie jest prawidłowe.
1) Upewnij się, że rozmiar contentSize jest większy niż UIScrollView
rozmiar ramki. Można zrozumieć, UIScrollViews
że UIScrollView
jest to okno do oglądania treści zdefiniowanej w contentSize. Gdy więc, UIScrollview
aby 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 UIScrollView
tak 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 UIScrollView
tak, aby gdy klawiatura była obecna, masz UIScrollView
okno rozmiar tylko do oryginalnej UIScrollView
ramki. 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ć CGRect
edytowane pole tekstowe i wywołać UIScrollView's
metodę scrollRecToVisible. Zaimplementowałem UITextFieldDelegate
metodę textFieldDidBeginEditing
za pomocą wywołania scrollRecToVisible
metody To faktycznie zadziałało z dziwnym efektem ubocznym, że przewijanie zatrzasnęło się UITextField
w pozycji. Najdłużej nie mogłem zrozumieć, co to było. Potem skomentowałem textFieldDidBeginEditing
metodę Delegata i wszystko działa !! (???). Jak się okazało, wierzę, że UIScrollView
faktycznie niejawnie przenosi aktualnie edytowane UITextField
do widocznego okna. Moja implementacja UITextFieldDelegate
metody i późniejsze wywołanie jej scrollRecToVisible
było zbędne i było przyczyną dziwnego efektu ubocznego.
Oto kroki, które należy wykonać, aby poprawnie przewinąć urządzenie UITextField
w odpowiednie UIScrollView
miejsce, 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
contentSize
jest ustawiony i większy niż twój UIScrollView
wviewDidLoad
- 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
UITextField
jest kartach nawet jeśli klawiatura jest już obecny, aby uniknąć kurczeniaUIScrollView
kiedy jest już skurczony
Jedną rzeczą do odnotowania jest to, że UIKeyboardWillShowNotification
uruchomi się nawet, gdy klawiatura jest już na ekranie, gdy tabulujesz inną UITextField
. Zadbałem o to, używając ivara, aby uniknąć zmiany rozmiaru, UIScrollView
gdy klawiatura jest już na ekranie. Nieumyślna zmiana rozmiaru, UIScrollView
gdy 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.