Флип-анимация iPhone с использованием UIViewAnimationTransitionFlipFromLeft в ландшафтном режиме - PullRequest
13 голосов
/ 18 апреля 2011

Я работаю над одним приложением для iPhone, в котором реализована одна анимация UIViewAnimationTransitionFlipFromLeft. Здесь мое приложение прекрасно работает в портретном режиме. Он выполняет ту же анимацию, что и указанное, означает перевернуть слева направо.

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

Код, который я использую для приложения iPhone для поворота вида, выглядит следующим образом:

   CGContextRef context = UIGraphicsGetCurrentContext();
    [UIView beginAnimations:nil context:context];
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view.window cache:NO];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:1.0];
    [UIView commitAnimations];
    [self.navigationController pushViewController:objSecond animated:YES];

Спасибо, С уважением, Гурприцингх Сайни

Ответы [ 5 ]

15 голосов
/ 22 мая 2011

Если вы используете iOS 4.0 или более позднюю версию, следующее будет делать именно то, что вы хотите (я только что проверил это)

NewView *myNewView = [[NewView alloc] initWith.....];
[UIView transitionFromView:self.view toView:myNewView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
//[self.navigationController pushViewController:myNewView animated:NO];
[myNewView release];

РЕДАКТИРОВАТЬ: я немного изменяю вышеуказанный код (ничего нового, просто закомментирую навигационный контроллер, потому что в этом нет необходимости).

Таким образом, есть несколько способов сделать это (чтобы отслеживать следующий вид), но это самый простой из всех, что я могу придумать. Вы уже можете переключиться с просмотра 1 на 2, поэтому я собираюсь объяснить, как получить от 2 до 10 (или сколько вам нужно).

По сути, переход представления длится слишком долго для viewDidLoad, чтобы перехватить вызов, чтобы перейти к следующему представлению. Поэтому нам нужно настроить таймер, который ожидает и отправляет метод для переключения позднее. Так что это код, который вы видите в представлении 2 (и 3 и 4 и т. Д.).

- (void)viewDidLoad {
    // this gets called before animation finishes, so wait;
    self.navigationController.delegate = self;
    // you will need to set the delegate so it can take control of the views to swap them;
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(switchView) userInfo:nil repeats:NO];
}

Я жду только 1 секунду, пока не вызову метод switch, но если вы много загружаете в свои представления, вы можете подождать немного дольше. 1,5 секунды должно быть более чем достаточно, но вы можете поиграть с этим, чтобы увидеть, где это работает и не работает.

Далее необходимо вызвать следующее представление в методе switchView.

- (void)switchView {
    NextView *myNextView = [[NextView alloc] initWith ... ];
    [UIView transitionFromView:self.view toView:nextView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
    [nextView release];
}

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

2 голосов
/ 19 апреля 2011

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

Обратите внимание, что аргумент контекста +beginAnimations:context: не должен быть CGContextRef как таковой. Вы, вероятно, не хотите передавать текущий графический контекст там. Вместо этого пройдите NULL.

1 голос
/ 23 мая 2011

Попробуйте с этим:

CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    CGFloat startValue = 0.0;
    CGFloat endValue = M_PI;
    rotateAnimation.fromValue = [NSNumber numberWithDouble:startValue];
    rotateAnimation.toValue = [NSNumber numberWithDouble:endValue];
    rotateAnimation.duration = 1.5;
    [self.view.layer addAnimation:rotateAnimation forKey:@"rotate"];
1 голос
/ 19 мая 2011
CGContextRef context = UIGraphicsGetCurrentContext();

[UIView beginAnimations:nil context:context];

[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO];

[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

[UIView setAnimationDuration:1.0];

[UIView commitAnimations];

Я думаю, что это сработает.

0 голосов
/ 08 июля 2013

Принятый ответ от slev у меня не сработал, я получил всевозможные ошибки после попытки кода в моем пользовательском Segue. Я нашел метод, который не только работает, но и более точен, поскольку не требует использования таймера. Вот MySegue.m:

@implementation FlipRightSegue

- (id)initWithIdentifier:(NSString *)iden source:(UIViewController *)sour destination:(UIViewController *)dest
{
    self = [super initWithIdentifier:iden source:sour destination:dest];

    return self;
}

- (void)perform
{

    UIViewController *src = [self sourceViewController];
    UIViewController *dst = [self destinationViewController];

    //[UIView transitionFromView:src.view toView:dst.view duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:nil];
    //[UIView commitAnimations];

    [UIView transitionWithView:src.navigationController.view duration:0.8 options:UIViewAnimationOptionTransitionFlipFromLeft
                   animations:^{
                       [src.navigationController pushViewController:dst animated:NO];
                   }
                   completion:NULL];
}

@end

У меня также есть второй класс для сальто справа. Код был взят с этого сайта: http://www.dailycode.info/Blog/post/2012/11/29/iOS-Custom-Flip-Segue-(portrait-and-landscape-layout)-xcode-4.aspx

...