У мене також було багато проблем із UIScrollViewскладанням множинUITextFields , з яких одна чи більше з них затуляються клавіатурою під час редагування.
Ось кілька речей, які слід врахувати, якщо ваш UIScrollView не правильно прокручуєте.
1) Переконайтеся, що UIScrollViewрозмір contentSize перевищує розмір кадру. Спосіб зрозуміти UIScrollViews, що UIScrollViewце схоже на вікно перегляду вмісту, визначеного в contentSize. Тож, коли для UIScrollviewпрокрутки кудись потрібно, розмір contentSize повинен бути більшим за UIScrollView. В іншому випадку не потрібно прокручування, оскільки все, що визначено в contentSize, вже видно. BTW, за замовчуванням 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встановлена і більше , ніж ваш UIScrollViewATviewDidLoad
- Плівки
UIScrollView , коли клавіатура присутня
- Відкат назад
UIScrollView коли клавіатура йде.
- Використовуйте Івар , щоб виявити , якщо клавіатура вже відображається на екрані , так як повідомлення клавіатури надсилаються кожен раз , коли
UITextFieldце закладками , навіть якщо клавіатура вже присутня , щоб уникнути усадкиUIScrollView , коли він вже усадки
Варто зауважити, що UIKeyboardWillShowNotificationзапускається навіть тоді, коли клавіатура вже на екрані, коли ви клацнете іншу UITextField. Я подбав про це, використовуючи ivar, щоб уникнути зміни розміру, UIScrollViewколи клавіатура вже на екрані. Мимоволі зміни розміру, UIScrollViewколи клавіатура вже є, було б катастрофічно!
Сподіваюся, що цей код рятує від вас багато головного болю.