简体   繁体   English

UIViewController过渡-Objective-C

[英]UIViewController transition - objective-c

I have UIViewControllers A and B, they are allocated in AppDelegate . 我有UIViewControllers A和B,它们分配在AppDelegate I need to apply transition to them. 我需要对他们进行过渡。 How to transit them without reallocating and replacing UIViews ? 如何在不重新分配和替换UIViews情况下迁移它们? This code calls from my UIBarButtonItem in UINavigationController : 这段代码从UINavigationController UIBarButtonItem调用:

[UIView transitionFromView:self.view  //UIViewController A
                           toView:appDelegate.secondViewController.view //UIViewController B
                           duration:0.5 
                           options:UIViewAnimationOptionTransitionFlipFromLeft   

This method replaces UIViews in my UIViewControllers , and I can transit them back, or just don't know how to do that. 此方法替换UIViews在我UIViewControllers ,我可以转换他们回来,或者只是不知道该怎么做。 Can you tell me how to do this? 你能告诉我怎么做吗?

If you're in iOS 5 world and want to jump between various view controllers, you might want to pursue View Controller Containment . 如果您在iOS 5世界中,并且想在各种视图控制器之间跳转,则可能需要追求View Controller Containment Or check out WWDC 2011 session 102 . 或查看WWDC 2011会议102

View controller containment basically assumes that you have some parent view controller which is governing the navigation between multiple child controllers. 视图控制器包含基本上假定您有一些父视图控制器,该父视图控制器控制着多个子控制器之间的导航。 In your case, the parent view would be one with the navigation bar with the button on it. 在您的情况下,父视图将是一个带有导航栏并带有按钮的视图。

Update: 更新:

If you pursue containment, you could create a parent view controller that has a nav bar with the button on it. 如果要进行遏制,则可以创建一个带有导航栏并带有按钮的父视图控制器。 When you load that view, you can add the first child view. 加载该视图时,可以添加第一个子视图。 Thus viewDidLoad might look like: 因此, viewDidLoad可能类似于:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // this is my model, where I store data used by my view controllers

    _model = [[MyModel alloc] init];

    // let's create our first view controller

    OneViewController *controller = [[OneViewController  alloc] initWithNibName:@"OneViewController"  bundle:nil];

    // pass it our model (obviously, `model` is a property that I've set up in my child controllers)

    controller.model = _model;

    // let's put the new child in our container and add it to the view

    [self addChildViewController:controller];
    [self configureChild:controller];
    [self.view addSubview:controller.view];
    [controller didMoveToParentViewController:self];

    // update our navigation bar title and the label of the button accordingly

    [self updateTitles:controller];
}

The configureChild just does final configuration. configureChild只是进行最终配置。 As a matter of convenience, I frequently will have a UIView that I've set up in IB (in this case, called childView ) which I use for setting up the frame, which gets me out of the world of manually creating frames, but you can do it any way you want: 为了方便起见,我经常会在IB中设置一个UIView(在本例中称为childView ),该UIView用于设置框架,这使我脱离了手动创建框架的世界,但是您可以按照任何想要的方式进行操作:

- (void)configureChild:(UIViewController *)controller
{
    // configure it to be the right size (I create a childView in IB that is convenient for setting the size of the views of our child view controllers)

    controller.view.frame = self.childView.frame;
}

This is the action if you touch the button in the navigation bar. 如果您触摸导航栏中的按钮,则将执行此操作。 If you're in the first controller, set up the second controller. 如果您在第一个控制器中,请设置第二个控制器。 If you're in the second controller, set up the first one: 如果您在第二个控制器中,请设置第一个:

- (IBAction)barButtonTouchUpInside:(id)sender 
{
    UIViewController *currentChildController = [self.childViewControllers objectAtIndex:0];

    if ([currentChildController isKindOfClass:[OneViewController class]])
    {
        TwoViewController *newChildController = [[TwoViewController alloc] initWithNibName:@"TwoViewController"  bundle:nil];
        newChildController.model = _model;
        [self transitionFrom:currentChildController To:newChildController];
    }
    else if ([currentChildController isKindOfClass:[TwoViewController class]])
    {
        OneViewController *newChildController = [[OneViewController alloc] initWithNibName:@"OneViewController"  bundle:nil];
        newChildController.model = _model;
        [self transitionFrom:currentChildController To:newChildController];
    }
    else
        NSAssert(FALSE, @"Unknown controller type");

}

This does the basic transition (including the various containment related calls): 这会进行基本转换(包括与收容相关的各种调用):

- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{    
    [self addChildViewController:newController];
    [self configureChild:newController];

    [self transitionFromViewController:oldController 
                      toViewController:newController
                              duration:0.5
                               options:UIViewAnimationOptionTransitionCrossDissolve
                            animations:^{
                                [self updateTitles:newController];
                            }
                            completion:^(BOOL finished){
                                [oldController willMoveToParentViewController:nil];
                                [oldController removeFromParentViewController];
                                [newController didMoveToParentViewController:self];
                            }];
}

This method just sets up the title in the nav bar in our parent view controller based upon which child is selected. 此方法只是根据选择的子级在我们的父级视图控制器的导航栏中设置标题。 It also sets up the button to reference the other controller. 它还设置按钮以引用其他控制器。

- (void)updateTitles:(UIViewController *)controller
{
    if ([controller isKindOfClass:[OneViewController class]])
    {
        self.navigationItemTitle.title = @"First View Controller";  // current title
        self.barButton.title = @"Two";                              // title of button to take me to next controller
    }
    else if ([controller isKindOfClass:[TwoViewController class]])
    {
        self.navigationItemTitle.title = @"Second View Controller"; // current title
        self.barButton.title = @"One";                              // title of button to take me to next controller
    }
    else
        NSAssert(FALSE, @"Unknown controller type");
}

This all assumes you are going to create and destroy controllers as you jump between them. 所有这些都假定您将在它们之间跳转时创建和销毁控制器。 I generally do this, but use a model object to store my data so I keep whatever data I want. 我通常这样做,但是使用模型对象存储我的数据,以便保留所需的任何数据。

You said you don't want to do this "without reallocating and replacing UIViews": If so, you can also change the above code to create both child view controllers up-front and change the transition to be simply jump between them: 您说过不想“不重新分配和替换UIViews”来执行此操作:如果是这样,您还可以更改上面的代码以预先创建两个子视图控制器,并将转换仅在它们之间跳转即可:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // this is my model, where I store data used by my view controllers

    _model = [[MyModel alloc] init];

    // let's create our first view controller

    _controller0 = [[OneViewController  alloc] initWithNibName:@"OneViewController"  bundle:nil];
    _controller0.model = _model;
    [self addChildViewController:_controller0];
    [self configureChild:_controller0];
    [_controller0 didMoveToParentViewController:self];

    // let's create our second view controller

    _controller1 = [[OneViewController  alloc] initWithNibName:@"OneViewController"  bundle:nil];
    _controller1.model = _model;
    [self addChildViewController:_controller1];
    [self configureChild:_controller1];
    [_controller1 didMoveToParentViewController:self];

    // let's add the first view and update our navigation bar title and the label of the button accordingly

    _currentChildController = _controller0;
    [self.view addSubview:_currentChildController.view];
    [self updateTitles:_currentChildController];
}

- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{    
    [self transitionFromViewController:oldController 
                      toViewController:newController
                              duration:0.5
                               options:UIViewAnimationOptionTransitionCrossDissolve
                            animations:^{
                                [self updateTitles:newController];
                            }
                            completion:^(BOOL finished){
                                _currentChildController = newController;
                            }];
}

- (IBAction)barButtonTouchUpInside:(id)sender 
{
    UIViewController *newChildController;

    if ([_currentChildController isKindOfClass:[OneViewController class]])
    {
        newChildController = _controller1;
    }
    else if ([_currentChildController isKindOfClass:[TwoViewController class]])
    {
        newChildController = _controller0;
    }
    else
        NSAssert(FALSE, @"Unknown controller type");

    [self transitionFrom:_currentChildController To:newChildController];

}

I've seen it both ways, so you can do whatever works for you. 我已经看过两种方式,因此您可以为自己做任何事情。

please see here . 请看这里 You basically want to implement UIViewController containment which is a new feature in iOS5. 您基本上想实现UIViewController包含,这是iOS5中的新功能。 The link provided above provides some code and a link to a github project. 上面提供的链接提供了一些代码以及指向github项目的链接。

Good luck 祝好运

t Ť

I found solution for my problem. 我找到了解决问题的方法。 This code works on iOS 4.x 此代码在iOS 4.x上有效

[UIView beginAnimations:@"transition" context:nil];
[UIView setAnimationDuration:1.0];

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

[self.navigationController 
pushViewController:self.alternateView animated:NO];

[UIView commitAnimations];

try 尝试

UIViewController* controller1;
UIViewController* controller2;
[controller1 transitionFromViewController:controller1 toViewController:controller2 duration:0.5f options:0 animations:nil completion:nil];

or 要么

if on top of navigationtroller - controller1 then 如果在navigationtroller-controller1上,则

UINavigationController* nav;
[nav pushViewController:controller2 animated:YES];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM