8

我正在寻找使用 curl up 动画执行 segue 以将窗口的根视图控制器替换为另一个视图控制器。这个想法是,在使用 curl up 动画转换 ( ) 到下一个之前,我会SplashViewController显示几秒钟。performSegueWithIdentifier:LoginViewController

我创建了一个UIStoryboardSegue名为AnimatedSegue. 下面是重写perform方法的代码:

- (void)perform
{
  UIViewController *source = self.sourceViewController;
  UIViewController *destination = self.destinationViewController;

  UIWindow *window = source.view.window;

  [UIView transitionFromView:source.view
                      toView:destination.view
                    duration:1.0
                     options:UIViewAnimationOptionTransitionCurlUp
                  completion:^(BOOL finished) {
                    [window setRootViewController:destination];
                  }];
}

它工作正常,除了在 iOS 6 中(显然不是在 iOS 5 中)该方法在视图控制器viewWillAppear:上被调用两次。destination似乎它在过渡期间被称为第一次,在执行时被称为第二次[window setRootViewController:destination];

请注意,我不想使用导航控制器。SplashViewController一旦过渡结束,就会被释放(如预期的那样)。

关于如何解决我的问题的任何想法?

4

3 回答 3

10

回答我自己的问题,以防它可以帮助别人......

我最终使用Core AnimationCATransition类来创建 segue 的动画而不是 的UIView动画方法。

这是我的新perform方法的样子:

- (void)perform
{
  UIViewController *source = self.sourceViewController;
  UIWindow *window = source.view.window;

  CATransition *transition = [CATransition animation];
  [transition setDuration:1.0];
  [transition setDelegate:self];
  [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
  [transition setType:@"pageCurl"];
  [transition setSubtype:kCATransitionFromBottom];

  [window.layer addAnimation:transition forKey:kCATransition];
  [window setRootViewController:self.destinationViewController];
}
于 2012-10-18T03:36:48.120 回答
2

我可能会以不同的方式执行此操作,使用 2 个视图和一个控制器,而不是使用自定义 segue 的 2 个控制器。在您的情节提要中,只需为控制器创建一个空白视图,然后添加两个带有初始视图和一个主视图的 xib 文件(视图类型)。初始视图将作为控制器视图的子视图添加到 viewDidLoad 中,然后使用您所做的相同方法切换出来:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.splashView = [[NSBundle mainBundle] loadNibNamed:@"SplashView" owner:self options:nil].lastObject;
    [self.view addSubview:self.splashView];
    [self performSelector:@selector(removeSplash) withObject:nil afterDelay:2];
}

-(void)removeSplash {
    self.mainView = [[NSBundle mainBundle] loadNibNamed:@"MainView" owner:self options:nil].lastObject;
    [UIView transitionFromView: self.splashView toView:self.mainView duration:.6 options:UIViewAnimationOptionTransitionCurlUp
                    completion:nil];
}
于 2012-10-17T22:41:49.453 回答
1

如果你真的,真的想使用transitionFromView:我能找到的唯一可行的方法就是创建源视图控制器的屏幕截图,并为其设置动画。

- (void)perform
{
    UIViewController *source = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;

    // Create screenshot for animation
    UIGraphicsBeginImageContextWithOptions(source.view.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [source.view.layer renderInContext:context];
    UIImageView *screenShot = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
    UIGraphicsEndImageContext();

    // Put destination view controller and screen shot in place
    UIWindow *window = source.view.window;
    window.rootViewController = destination;
    [window addSubview:screenShot];

    [UIView transitionFromView:screenShot
                        toView:destination.view
                      duration:1.0
                       options:UIViewAnimationOptionTransitionCurlUp
                    completion:^(BOOL finished) {
                    }];
}

viewWillAppear:并且它的同类只按预期被调用一次。

于 2013-07-26T17:40:44.690 回答