self.view.frame больше не анимируется в начальном контроллере представления раскадровки.

Это странная проблема. У меня есть контроллер просмотра iPhone для создания нового пользователя с некоторыми текстовыми полями, для которых требуется анимация, чтобы избежать клавиатуры при ее отображении, т.е. представление анимируется вверх и вниз, чтобы сохранить минимальный зазор между верхней частью клавиатуры и нижним краем текстовое поле. Это работало нормально, когда оно было представлено модально с экрана входа в систему существующего пользователя, начального контроллера представления в раскадровке.

Затем я решил немного изменить приложение, чтобы представления пользователя для входа/создания принадлежали одному и тому же контроллеру представления. Они переходят так:

if(accountCreateView == nil) {
    UINib *nib = [UINib nibWithNibName:@"NewAccountView" bundle:nil];
    NSArray *nibViews = [nib instantiateWithOwner:self options:nil];
    accountCreateView = [nibViews objectAtIndex:0];
}

[UIView transitionFromView:(displayingLoginView ? loginView : accountCreateView)
                    toView:(displayingLoginView ? accountCreateView : loginView)
                  duration:0.6
                   options:(displayingLoginView ? 
                            UIViewAnimationOptionTransitionFlipFromRight :
                            UIViewAnimationOptionTransitionFlipFromLeft)
                completion:^(BOOL finished) {
                    if (finished) {
                        displayingLoginView = !displayingLoginView;
                    }
                }
];

Это тоже отлично работает. Однако код, который выполняет анимацию представлений, этого не делает. Когда текстовое поле становится активным, вызывается код для проверки близости текстового поля к клавиатуре, но при выполнении блока анимации ничего не происходит.

Итак, я проверил:

if([UIView areAnimationsEnabled])
    NSLog(@"Animations are enabled");
else 
    NSLog(@"Animations are disabled");

Анимация конечно включена.

Поэтому я переместил его обратно к viewDidLoad, попробовав простую анимацию, чтобы увидеть, что работает, прежде всего:

CGRect viewFrame = loginNameTextField.frame;
viewFrame.origin.y = 400.f;
[UIView animateWithDuration:1.f 
                      delay:0.f 
                    options:UIViewAnimationOptionCurveEaseInOut 
                 animations:^ {
                     loginNameTextField.frame = viewFrame;
                 }
                 completion:NULL];

Это отлично работает! Текстовое поле медленно перемещается вниз по окну.

Это ничего не делает, и это запутанная часть:

CGRect viewFrame = self.view.frame;
viewFrame.origin.y = 400.f;
[UIView animateWithDuration:1.f 
                      delay:0.f 
                    options:UIViewAnimationOptionCurveEaseInOut 
                 animations:^ {
                     self.view.frame = viewFrame;
                 }
                 completion:NULL];

viewFrame при установке из self.view.frame имеет происхождение 0,20 и размер 320 460, как и ожидалось.

Я попытался установить свойство фрейма напрямую:

CGRect viewFrame = self.view.frame;
viewFrame.origin.y = 400.f;
self.view.frame = viewFrame;

Похоже, я могу изменить рамку подвидов self.view, но не self.view. Исправление может заключаться в том, чтобы оставить начальный контроллер представления пустым представлением в раскадровке и создать xib как для представления входа в систему, так и для создания пользовательского представления и загрузить их в viewDidLoad, но почему?

edit: Да, переключение версии раскадровки контроллера представления на простое пустое представление и добавление представления, содержащего фактический пользовательский интерфейс, из xib в качестве подпредставления, заставляет анимацию снова работать. Хотя до сих пор не знаю, почему.


person Adam Eberbach    schedule 01.02.2012    source источник


Ответы (1)


Если все, что вам нужно сделать, это разместить текстовые поля над клавиатурой, почему бы не отказаться от UIViewController и перейти на UITableViewController и использовать статические ячейки? Вы размещаете одно текстовое поле в каждой ячейке (создавая достаточно ячеек для удовлетворения ваших потребностей) и стилизуете его по своему усмотрению. Когда у вас нет первого ответчика и на экране недостаточно ячеек, он не будет прокручиваться. Если их больше, чем поместится, то он будет прокручиваться, чтобы достичь нижних/верхних ячеек. Тем не менее, независимо от того, сколько у вас ячеек, если вы выберете текстовое поле, которое будет закрыто клавиатурой, устройство автоматически прокрутит ячейку до видимой позиции. Это все встроено, и я использую эту функцию все время. Он работает с текстовыми полями и текстовыми представлениями. Просто не забудьте закомментировать количество разделов, количество строк в разделе и ячейку для методов пути индекса, чтобы статические ячейки работали правильно. Это экономит много кода.

ХТН

Роб

person Rob    schedule 01.02.2012
comment
Это хорошая идея, и я вижу, что это удобно с автоматической прокруткой (или изменением рамки таблицы, а затем использованием scrollToRowAtIndexPath), но представление немного сложнее, чем то, поэтому мне нужно просто сдвинуть содержащее представление. - person Adam Eberbach; 02.02.2012
comment
Ok. Я подумал, что добавлю в свой пост, что в некоторых случаях также помогает иметь представление верхнего и нижнего колонтитула в UITableView. Вы можете разместить в них более сложные вещи, если это поможет. Конечно, это ограничивает вас размещением жестких элементов вверху и внизу представления таблицы, что может быть нежелательно в зависимости от вашего дизайна. - person Rob; 02.02.2012