У меня также было много проблем с UIScrollViewсозданием нескольких UITextFields, из которых один или несколько из них были бы скрыты клавиатурой при редактировании.
Вот некоторые вещи, которые следует учитывать, если вы UIScrollViewне прокручиваете их должным образом.
1) Убедитесь, что ваш contentSize больше UIScrollViewразмера кадра. Способ понять UIScrollViews, что UIScrollViewэто похоже на окно просмотра контента, определенного в contentSize. Поэтому, когда для UIScrollviewпрокрутки в любом месте, contentSize должен быть больше, чем UIScrollView. Иначе, прокрутка не требуется, так как все, что определено в contentSize, уже видно. Кстати, по умолчанию contentSize = CGSizeZero.
2) Теперь, когда вы понимаете, что на UIScrollViewсамом деле окно в ваш «контент», способ гарантировать, что клавиатура не заслоняет ваше UIScrollView's«окно» просмотра, состоит в изменении размера UIScrollViewтак, чтобы при наличии клавиатуры у вас было UIScrollViewокно по размеру соответствует только оригинальному UIScrollViewframe.size.height минус высота клавиатуры. Это гарантирует, что ваше окно будет только этой маленькой видимой областью.
3) Вот подвох: когда я впервые реализовал это, я подумал, что мне нужно получить CGRectотредактированное текстовое поле и вызвать UIScrollView'sметод scrollRecToVisible. Я реализовал UITextFieldDelegateметод textFieldDidBeginEditingс помощью вызова scrollRecToVisibleметода. Это на самом деле работали со странным побочным эффектом , что скроллинг будет оснасткойUITextField в положение. Долгое время я не мог понять, что это было. Затем я прокомментировал textFieldDidBeginEditingметод Delegate, и все это работает !! (???). Как выяснилось, я считаю, что UIScrollViewфактически неявно переносит редактируемое UITextFieldв настоящее время в видимое окно неявно. Моя реализация UITextFieldDelegateметода и последующий вызов к нему scrollRecToVisibleбыли излишни и стали причиной странного побочного эффекта.
Так вот шаги , чтобы правильно прокручивает UITextFieldв UIScrollViewна место , когда появляется значок клавиатуры.
// 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;
}
- Зарегистрируйтесь для получения уведомлений клавиатуры
viewDidLoad
- Отменить регистрацию для клавиатурных сообщений на
viewDidUnload
- Убедитесь, что
contentSizeустановлено и больше, чем у вас UIScrollViewвviewDidLoad
- Термоусадочные
UIScrollView , когда клавиатура присутствует
- Откат назад
UIScrollView когда клавиатура уходит.
- Используйте Ивар , чтобы обнаружить , если клавиатура уже отображается на экране , так как уведомления клавиатуры посылаются каждый раз , когда
UITextFieldэто закладками , даже если клавиатура уже присутствует , чтобы избежать усадкиUIScrollView , когда он уже усадке
Стоит отметить, что при UIKeyboardWillShowNotificationсрабатывании другой клавиши она будет срабатывать даже тогда, когда клавиатура уже находится на экране UITextField. Я позаботился об этом, используя ivar, чтобы избежать изменения размера, UIScrollViewкогда клавиатура уже находится на экране. Случайное изменение размера, UIScrollViewкогда клавиатура уже есть, будет катастрофическим!
Надеюсь, этот код избавит некоторых из вас от головной боли.