Как добиться плавной анимации при использовании одношагового поворота / Как получить новый размер кадра в начале поворота? - PullRequest
4 голосов
/ 16 августа 2010

Я пытаюсь переключиться с двухступенчатого вращения на одноступенчатое вращение (чтобы избежать предупреждения консоли, и потому что Apple рекомендует делать это, потому что одноступенчатое вращение быстрее).

Как я могу 't выяснить, как получить новый размер моего вида (с учетом панели навигации, строки состояния и т. д.) достаточно рано, чтобы выполнить обновление моего пользовательского интерфейса во время анимации (а не просто привязать элементы к их новым позициям вконец, как это делают многие приложения, что приводит к большому «рывку» в конце анимации).

Размеры, которые я получаю в методе willAnimateRotationToInterfaceOrientation:duration:, - это (возможно, очевидно) старые размеры.

Я вижу, что должен уметь вычислять его вручную, вычисляя текущую высоту стержня, а затем выводя новый размер кадра просмотра, вычитая их из размеров повернутого экрана?(что не так сложно сделать, хотя, возможно, хрупко, так как предполагает, что панель навигации, строка состояния и т. д. будут иметь одинаковую высоту в обеих ориентациях, и вам придется вручную учитывать, что панель инструментов имеет разную высоту впортрет против пейзажа - я просто хочу убедиться, что я не пропустил более простой или общепринятый способ.)

Любые отзывы о подходах других людей были бы великолепны!

Спасибо

Джозеф

Ответы [ 4 ]

5 голосов
/ 21 августа 2010

Я добился наибольшего успеха, используя метод layoutSubviews моего представления для авторотаций. Когда layoutSubviews вызывается во время изменения ориентации, границы представления уже установлены на то, что они будут в конце поворота. В это время вы также можете запросить у строки состояния, панели навигации и панели инструментов их размеры и получить правильные значения после поворота (хотя ширина и высота строки состояния могут меняться местами - я просто принимаю меньшее значение в качестве высоты, работает отлично). Используя эту информацию, вы можете выложить подпредставления, и они будут анимированы как часть ротации.

Создание подкласса UIView для каждой ситуации, в которой вы хотите это сделать, может раздражать, поэтому я создал специальный подкласс UIView под названием DelegatingView, который выглядит следующим образом:

@protocol DelegatingViewDelegate

- (void)layoutSubviewsForView:(UIView*)view;

@end

@interface DelegatingView : UIView {
    id<DelegatingViewDelegate> _delegate;
}

@property (nonatomic,assign) id<DelegatingViewDelegate> delegate;

@end

@implementation DelegatingView

@synthesize delegate = _delegate;

- (void)layoutSubviews {
    [super layoutSubviews];
    [_delegate layoutSubviewsForView:self];
}

@end

Я использую это как базовое представление, добавляю к нему подпредставления и устанавливаю свой UIViewController в качестве делегата. Затем я могу размещать подпредставления из моего контроллера представления, имея доступ к текущей ориентации и т. Д.

3 голосов
/ 21 августа 2010

На какую версию ОС вы ориентируетесь? В OS 4.0 (что я и сделал для быстрого теста), [view bounds] в willAnimateRotationToInterfaceOrientation:duration: возвращает новые границы после поворота.

Если вы этого не видите, я бы посоветовал еще раз проверить, что в вашем представлении установлена ​​соответствующая маска автоматического изменения размера.

2 голосов
/ 24 августа 2010

Если у вас есть сложные требования к макету в представлении вашего контроллера представления, стоит создать подкласс UIView и выполнить код макета в -layoutSubviews (правильное место для создания макета представления). Как отметил Хилтон Кэмпбелл, если вы используете этот метод для разметки, вы можете проверить размеры фреймов и отношения подпредставления и соответственно установить их новые позиции.

Если представление вашего контроллера представления имеет простой набор подпредставлений, то вам, вероятно, следует просто соответствующим образом установить их свойства autoresizingMask и позволить им автоматически анимировать себя.

0 голосов
/ 25 августа 2010

Я попытался двумя способами отрегулировать размер представления.

1.) Уведомить дочерние представления, чтобы настроить их размер после - (void) viewWillAppear;Недостатком является то, что он будет выполняться каждый раз, когда viewWillAppear.

ex:

<code>
- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self notifyChildViewWillAppear:animated];
}</p>

<p>at child view
- (void)notifyChildViewWillAppear:(BOOL)animated
{
   // at this time, the size of superview's bounds 
   //equals the content view's size 
   // (no navigationBar's height and toolbar's height.
   self.frame = [self superview].bounds;
}</p>

<p>

2.) Рассчитать необходимый размер вручную.Я рассчитываю как viewDidLoad.Размеры навигационной панели и панели инструментов можно определить с помощью следующего кода.

<code>
self.navagationController.navigationBar.view.frame.size.height;
self.tabBarController.tabBar.frame.size.height;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...