CATransition не учитывает изменения ориентации на iPad

У меня есть работающий завиток страницы, который работает. Проблема в вращении iPad. Приложение работает только в альбомной ориентации и поддерживает l влево и l вправо. Если iPad находится в горизонтальном положении, скручивание происходит в правом нижнем углу, как и должно быть. Если я поворачиваю iPad, вид поворачивается, как и ожидалось, но теперь, когда я пытаюсь, скручивание происходит в левом верхнем углу. Я добавил уведомление, чтобы сообщить мне, когда оно вращается, и попытаться изменить подтип анимации, но не кости.

   -(IBAction)curlViewUp
{
    uiv_help.alpha = 1.0;

    [UIView animateWithDuration:1.0
                     animations:^{
                         CATransition *animation = [CATransition animation];
                         [animation setDelegate:self];
                         [animation setDuration:0.7];
                         [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
                         animation.type = @"pageCurl";
                         animation.subtype = curlDirection;
                         animation.fillMode = kCAFillModeForwards;
                         animation.endProgress = 0.20;
                         [animation setRemovedOnCompletion:NO];
                         [self.view.layer addAnimation:animation forKey:@"pageCurlAnimation"];
                         [self.view addSubview:uiv_help];
                         ;}
     ];
}

-(IBAction)curlViewDown
{
    uiv_help.alpha = 0.0;

    [UIView animateWithDuration:1.0
                     animations:^{
                         CATransition *animation = [CATransition animation];
                         [animation setDelegate:self];
                         [animation setDuration:0.7];
                         [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
                         animation.type = @"pageUnCurl";
                         animation.subtype = curlDirection;
                         animation.fillMode = kCAFillModeForwards;
                         animation.startProgress = 0.80;
                         [animation setRemovedOnCompletion:YES];
                         [self.view.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];
                         //[self.view removeFromSuperview];
                         [uiv_help removeFromSuperview];
                         ;}
     ];

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft | interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft)
    {
        NSLog(@"UIInterfaceOrientationLandscapeLeft");

        curlDirection = @"fromRight";
    } else if (orientation == UIInterfaceOrientationLandscapeRight) {
        NSLog(@"UIInterfaceOrientationLandscapeRight");

        curlDirection = @"fromRight";
    }
}

person malaki1974    schedule 13.11.2012    source источник
comment
Я думаю, это должно быть ошибка uikit или что-то в этом роде...   -  person jonydep    schedule 03.01.2013
comment
Вероятно, это была просто опечатка, когда вы скопировали его в StackOverflow, но здесь написано curlDirection = @fromRight, независимо от того, является ли ориентация l левой или l правой.   -  person Austin Mullins    schedule 10.01.2013
comment
почему люди предлагают награды, если они не собираются их выполнять?   -  person foundry    schedule 10.01.2013
comment
@AustinMullins, я был бы признателен, если бы вы могли взглянуть на мой ответ на этот вопрос, и если вы одобряете, проголосуйте за него. Похоже, что вопрос был оставлен как ОП, так и предлагающим вознаграждение. Я предоставил подробный, полезный, правильный ответ (проверено), который будет потерян и проигнорирован .. спасибо   -  person foundry    schedule 11.01.2013
comment
@Он был ??? Прошел всего день с момента публикации ответа - с тех пор я не включал свой компьютер. Я счастлив присудить щедрость.   -  person jonydep    schedule 11.01.2013
comment
Спасибо jonydep. Я подозреваю, что не понимаю систему наград. Я думал, что по истечении срока действия награда была потеряна для обеих сторон.   -  person foundry    schedule 11.01.2013
comment
Не заброшен - просто занят в данный момент. Обещаю, проголосую, если правильно...   -  person malaki1974    schedule 12.01.2013


Ответы (1)


Ваш pagecurl не вращается вместе с устройством.

Это потому, что его вид не вращается вместе с вращением устройства.

Это потому, что это представление является самым верхним представлением в иерархии представлений.

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

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

Вот мы и в портретном режиме. Я создал подвид, содержащийся внутри self.view, с теми же размерами.

self.view frame {{0, 20}, {768, 1004}}
self.view bounds {{0, 0}, {768, 1004}}
self.view center {384, 522}
--------
self.subview frame {{0, 0}, {768, 1004}}
self.subview bounds {{0, 0}, {768, 1004}}
self.subview center {384, 502}

Теперь давайте повернем в ландшафт

self.view frame {{20, 0}, {748, 1024}}
self.view bounds {{0, 0}, {1024, 748}}
self.view center {394, 512}
--------
self.subview frame {{0, 0}, {1024, 748}}
self.subview bounds {{0, 0}, {1024, 748}}
self.subview center {512, 374}

вы увидите, что внутреннее подпредставление правильно сообщает ширину как 1024 и высоту как 748px. но внешний вид просто стал странным. Его рамка сообщает ширину 748 и высоту 1024, как будто она все еще портретная (с добавлением строки состояния 20 пикселей). Но его границы говорят нам, что это пейзаж.

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

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

Измените эту строку:

[self.view.layer addAnimation:animation forKey:@"pageCurlAnimation"];

to

[self.subview.layer addAnimation:animation forKey:@"pageCurlAnimation"];

и измените эту строку:

[self.view.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];

to:

[self.subview.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];

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

Вы можете добиться того же результата без изменения кода, но внедрив свой viewController в UINavigationViewController. В этом случае представление NavViewController является самым внешним видом, который не вращается. Таким образом, ваше представление о себе будет вращаться.

обновить

UIWindow* mWindow = [[UIApplication sharedApplication] keyWindow];
UIView *topView = [[mWindow subviews] lastObject];
NSLog("%@",topView);


topView <UILayoutContainerView: 0x71eb450; 
frame = (0 0; 748 1024); 
transform = [0, 1, -1, 0, 0, 0];     
autoresize = W+H; gestureRecognizers = <NSArray: 0x71f8a30>; 
layer = <CALayer: 0x71eb540>>

Обратите внимание на преобразование.

person foundry    schedule 10.01.2013
comment
К сожалению, UINavigationViewController совсем не помогает. Применение перехода curl к navcontroller pushviewController приведет к ошибочному поведению: curl игнорирует ориентацию устройства. - person Cross_; 07.02.2013