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