У меня также было много проблем с UIScrollView
созданием нескольких UITextFields
, из которых один или несколько из них были бы скрыты клавиатурой при редактировании.
Вот некоторые вещи, которые следует учитывать, если вы UIScrollView
не прокручиваете их должным образом.
1) Убедитесь, что ваш contentSize больше UIScrollView
размера кадра. Способ понять UIScrollViews
, что UIScrollView
это похоже на окно просмотра контента, определенного в contentSize. Поэтому, когда для UIScrollview
прокрутки в любом месте, contentSize должен быть больше, чем UIScrollView
. Иначе, прокрутка не требуется, так как все, что определено в contentSize, уже видно. Кстати, по умолчанию contentSize = CGSizeZero
.
2) Теперь, когда вы понимаете, что на UIScrollView
самом деле окно в ваш «контент», способ гарантировать, что клавиатура не заслоняет ваше UIScrollView's
«окно» просмотра, состоит в изменении размера UIScrollView
так, чтобы при наличии клавиатуры у вас было UIScrollView
окно по размеру соответствует только оригинальному UIScrollView
frame.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
когда клавиатура уже есть, будет катастрофическим!
Надеюсь, этот код избавит некоторых из вас от головной боли.