неправильная ориентация на UIViewController при его анимации - PullRequest
3 голосов
/ 08 марта 2011

Чтобы использовать UISplitViewController, я заменяю свой корневой оконный контроллер при переходе от одного контроллера представления к другому.

Для того, чтобы сделать при этом хороший переход, я используюэффект масштабирования подобен этому:

MyOtherViewController *controller = [[MyOtherViewController alloc] initWithNibName:@"MyOtherView" bundle:nil];
UIWindow *window = ((MyAppDelegate *)[[UIApplication sharedApplication] delegate]).window;

controller.view.frame = [window frame];
controller.view.transform = CGAffineTransformMakeScale(0.01,0.01);
controller.view.alpha = 0;

[window addSubview:controller.view];

[UIView animateWithDuration:0.2 animations:^{
    controller.view.transform = CGAffineTransformMakeScale(1,1);
    controller.view.alpha = 1.0;
} completion:^(BOOL finished) {
    if (finished) { 
        [self.view removeFromSuperview];
         window.rootViewController = controller;
    }
}];

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

Чего мне не хватает?

Вещи, которые я пробовал:

  • , выставив мой новый вид контроллера какединственное подпредставление UIWindow
  • , делающее мой новый контроллер корневым контроллером представления перед началом анимации

Любопытно, что, если я делаю recursiveDescription для окна в началемоего метода, оконная рама определена как имеющая размер 768x1024 (т.е. портрет) и вид внутри нее 748x1024, но с преобразованием [0, -1, 1, 0, 0, 0] (делает этоозначает вращение или что? Разве это не должно быть преобразование идентичности?)

Ответы [ 2 ]

3 голосов
/ 08 марта 2011

UIWindow не вращается. Он имеет вращающийся вид внутри (как вы видели). В этом случае, однако, я думаю, что проблема, скорее всего, заключается в том, что ваше представление уже имеет преобразование на этом этапе, и вам нужно объединить его, а не заменить его, как вы делаете в своих вызовах setTransform:.

Вы не должны спрашивать у окна приложения представителя, вы должны получать окно из вида (self.view.window).

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

- (CGAffineTransform)effectiveTransform {
    CGAffineTransform transform = [self transform];
    UIView *view = [self superview];
    while (view) {
        transform = CGAffineTransformConcat(transform, [view transform]);
        view = [view superview];
    }
    return transform;
}
2 голосов
/ 09 марта 2011

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

Итак, без лишних слов, вот рабочий код:

MyOtherViewController *controller = [[MyOtherViewController alloc] initWithNibName:@"MyOtherView" bundle:nil];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];

CGAffineTransform t = self.view.transform;
controller.view.transform = t;
controller.view.frame = self.view.frame;
controller.view.transform = CGAffineTransformScale(t,.01,.01);;
[window addSubview:controller.view];

controller.view.alpha = 0;

[UIView animateWithDuration:0.2 animations:^{
    controller.view.transform = t;
    controller.view.alpha = 1.0;
} completion:^(BOOL finished) {
    if (finished) { 
        [self.view removeFromSuperview];
        window.rootViewController = controller;
        [controller release];
    }
}];
...