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, сякаш все още е портрет (с добавяне на лентата на състоянието 20px). Но границите ни казват, че е пейзаж.

Очевидно не искаме да разчитаме на геометричните свойства на изглед, който отчита такива странни резултати. Предполагам, че това е свързано с предупреждението на Apple, че не трябва да препращате към рамка на изглед, ако е била обект на трансформация, различна от трансформацията на самоличността.

Решението е да вградите вашия pagecurling изглед в друг най-външен изглед. Създайте нов изглед, наречете го 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 е най-външният изглед, който не се върти. Така че вашият self.view ще се върти.

актуализация

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