视图控制器的转换 - 从左到右

4

我没有使用导航控制器,而是使用storyboards。

我需要从一个视图控制器过渡到另一个视图控制器,为此我使用segue。

现在我将segue样式设置为自定义,在相应的类中,我重写了perform方法。

-(void)perform
{
    UIViewController *sourceViewController = [self sourceViewController];
    UIViewController *destinationViewController = [self destinationViewController];

    CATransition *transition = [CATransition animation];
    transition.duration = 0.25;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;

    [sourceViewController.view.layer addAnimation:transition forKey:kCATransition];animated:NO];
    [sourceViewController presentViewController:destinationViewController animated:YES completion:nil];
}

但是目标视图控制器也有一个属性modalTransitionStyle

现在,源视图控制器从左到右移动,就像被推动一样,但我想显示它是由目标视图控制器推动的。相反,目标VC默认情况下执行“覆盖垂直”,并且modalTransitionStyle属性只有四个可用选项,其中没有一个适用于我。

我认为要使其工作,应该将此动画添加到某个父视图层,这是两个视图控制器都呈现的父视图。但是没有这样的父视图..

2个回答

7
通常情况下,您会将storyboardId分配给目标控制器,并从源视图控制器中这样调用它:
//push next view
UIStoryboard *storyboard = self.storyboard;
YourViewControllerClass *destVC = [storyboard instantiateViewControllerWithIdentifier:@"StoryboardID"];
[self.navigationController pushViewController:destVC animated:YES];

如果需要的话,您也可以手动完成此操作:

    // Get the views.
    UIView * fromView = sourceViewController.view;
    UIView * toView = destinationViewController.view;

    // Get the size of the view area.
    CGRect viewSize = fromView.frame;

    // Add the toView to the fromView
    [fromView.superview addSubview:toView];

    // Position it off screen.
    toView.frame = CGRectMake( 320 , viewSize.origin.y, 320, viewSize.size.height);

    [UIView animateWithDuration:0.4 animations:
     ^{
         // Animate the views on and off the screen. This will appear to slide.
         fromView.frame =CGRectMake( -320 , viewSize.origin.y, 320, viewSize.size.height);
         toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
     }
                     completion:^(BOOL finished)
     {
         if (finished)
         {
             // Remove the old view from its parent.
             [fromView removeFromSuperview];

             //I use it to have navigationnBar and TabBar at the same time
             //self.tabBarController.selectedIndex = indexPath.row+1;
         }
     }];

反向函数(类似于导航控制器中的返回按钮):

// Get the views.
UIView * fromView = fromViewController.view;
UIView * toView = destViewController.view;

// Get the size of the view area.
CGRect viewSize = fromView.frame;

// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];

// Position it off screen.
toView.frame = CGRectMake( -320 , viewSize.origin.y, 320, viewSize.size.height);

[UIView animateWithDuration:0.4 animations:
 ^{
     // Animate the views on and off the screen. This will appear to slide.
     fromView.frame =CGRectMake( 320 , viewSize.origin.y, 320, viewSize.size.height);
     toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
 }
                 completion:^(BOOL finished)
 {
     if (finished)
     {
         // Remove the old view from the tabbar view.
         [fromView removeFromSuperview];
     }
 }];

我没有使用导航控制器。你的第二种方法是否与“呈现”视图相同?我的意思是它会调用viewWillAppear和其他类似的方法吗?我能够“dismiss”视图吗,还是我要做类似于删除视图的操作? - neeraj
或者您能告诉我一些步骤,以便我可以将我的应用程序转换为使用导航控制器吗?我有VC1,它可以呈现VC2或VC3。 VC2和VC3彼此没有关系。 - neeraj
1
@neeraj 第二种方法将在右侧附加第二个视图,向右滑动直到只有该视图可见,然后关闭第一个视图。所有对应的方法,如 viewDidLoadviewWillAppear 将像往常一样被调用。如果你所说的“关闭”是指像 dismissModalViewControllerAnimated: 生成的行为,那么你可以通过调用一个功能来实现相同的效果,但顺序相反(将新视图附加到左侧并向左滑动)。 - Daniel
我想要视图控制器的动画 - 从上到下和从下到上的过渡,那么主要的变化是什么? - Aruna kumari
@Arunakumari 在设置框架时,请改变 origin.ysize.height 的值,并将 origin.xsize.width 的值设置为视图的值。 - Daniel
显示剩余4条评论

1

我的应用程序中的所有视图控制器都继承自MyViewController,除了其他默认行为外,还具有以下属性:

@property(readwrite, nonatomic) BOOL slideFromSide;

而这段代码:

- (void) presentViewController: (UIViewController*) vc animated: (BOOL) flag completion: (void (^)(void)) completion
{
    BOOL slideIn = NO;
    if ([vc isKindOfClass: [MyViewController class]])
    {
        MyViewController *svc = (MyViewController*) vc;
        slideIn = svc.slideFromSide;
    }

    if (slideIn)
    {
        [self addChildViewController: vc];
        [self.view addSubview: vc.view];

        CGRect frame = vc.view.frame;
        frame.origin.x = frame.size.width;
        vc.view.frame = frame;

        frame.origin.x = 0;
        [UIView animateWithDuration: 0.33
                         animations: ^{
                             vc.view.frame = frame;
                         }
         ];
    }
    else
    {
        [super presentViewController: vc animated: flag completion: completion];
    }
}


- (IBAction) backAction: (id) sender
{
    if (_slideFromSide)
    {
        CGRect frame = self.view.frame;
        frame.origin.x = frame.size.width;
        [UIView animateWithDuration: 0.33
                         animations: ^{
                             self.view.frame = frame;
                         }
                         completion:^(BOOL finished) {
                             [self removeFromParentViewController];
                         }
         ];
    }
    else
    {
        [self dismissViewControllerAnimated: YES completion: nil];
    }
}

然后,在我想要滑入的ViewControllers中,我有:

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName: nibNameOrNil bundle: nibBundleOrNil];
    if (self)
    {
        self.slideFromSide = YES;
        // Whatever else you want to do
    }

    return self;
}

调用一个新的视图控制器与普通操作一样:
WhateverViewController *vc = [WhateverViewController alloc] initWithNibName: nil bundle: nil];
[self presentViewController: vc animated: YES completion: nil];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接