自定义容器和自定义转换

时间:2013-11-16 21:13:25

标签: ios ios7

自定义过渡可以轻松使用标准容器,同时呈现模态视图控制器。但是使用完全自定义容器的自定义转换呢?

我想将UIViewControllerContextTransitioning协议与我的自定义容器一起使用,并利用转换和交互式转换。

UIViewControllerContextTransitioning标题文件的评论中,我读到了:

// The UIViewControllerContextTransitioning protocol can be adopted by custom
// container controllers.  It is purposely general to cover more complex
// transitions than the system currently supports. 

但我无法理解如何创建Context Transitioning并启动所有自定义转换过程。

4 个答案:

答案 0 :(得分:5)

这很有可能!

看看这个SO Answer

您只需要创建一个符合UIViewControllerContextTransitioning协议的viewController,并使用ViewController Containment API(addChildViewController:,willMoveToParentViewController:等等)。

如果要启动自定义转换,只需在transitionController上调用[animateTransition]方法即可。从那时起,它与Apple提供的API相同。

使用Transitioning API使您的自定义容器适合。

事实上,iOS7中引入的所有新协议(UIViewControllerContextTransitioning等)并不是真正需要实现自己的完全自定义的containerViewController。它只是提供了一个整洁的类关系和方法池。但是您可以自己编写所有内容,而不需要使用任何私有API。 ViewController Containment(在iOS5中引入)是您完成这项工作所需的全部内容。

我试过尝试过它甚至可以使用交互式过渡。

如果您需要一些示例代码,请告诉我,我会提供一些代码:)

修改

顺便说一句,这就是Facebook和Instagram for iOS创建导航概念的方式。你可以滚动这些应用程序中的NavigationBar,当一个新的ViewController被“推”时,NavigationBar似乎在推动过程中被重置了。

具有讽刺意味的是,我在一个月前在StackOverflow上问了完全相同的问题:D

My Question

我刚刚意识到我自己回答了问题:)

度过美好的一天!

答案 1 :(得分:1)

事实上,它是这样说但你不完整:

  

UIViewControllerContextTransitioning协议可以采用   定制容器控制器。覆盖是故意的   比系统当前支持的更复杂的转换。对于   现在,导航推/弹出和UIViewController存在/解除   过渡可以定制。

这意味着您可以通过调用transitioningDelegate方法触发VC presentViewController:animated:completion:,也可以在navigationController:animationControllerForOperation:fromViewController:toViewController:类中实现UINavigationControllerDelegate并返回符合UIViewControllerAnimatedTransitioning的对象}协议。

总而言之,提供自定义转换的方法只有两种。两者都需要在我们添加子视图时创建/推送VC以创建自定义容器视图控制器。

可能苹果将来会在头文件的第一行中说出他们所说的话,但是现在你想做的事情似乎是不可能的。

答案 2 :(得分:0)

来自docs UIViewControllerContextTransitioning

  

不要在自己的课程中采用此协议,也不应该   直接创建采用此协议的对象。

答案 3 :(得分:-2)

请查看MPFoldTransition,它对我有用。

您还可以使用以下类别,您可以使用此属性创建自己的过渡。

#import <UIKit/UIKit.h>

@interface UIView (Animation)

- (void) moveTo:(CGPoint)destination duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) downUnder:(float)secs option:(UIViewAnimationOptions)option;
- (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) removeWithZoomOutAnimation:(float)secs option:(UIViewAnimationOptions)option;
- (void) addSubviewWithFadeAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) removeWithSinkAnimation:(int)steps;
- (void) removeWithSinkAnimationRotateTimer:(NSTimer*) timer;

@end

实施:

#import "UIView+Animation.h"

@implementation UIView (Animation)

- (void) moveTo:(CGPoint)destination duration:(float)secs option:(UIViewAnimationOptions)option
{
    [UIView animateWithDuration:secs delay:0.0 options:option
                     animations:^{
                         self.frame = CGRectMake(destination.x,destination.y, self.frame.size.width, self.frame.size.height);
                     }
                     completion:nil];
}

- (void) downUnder:(float)secs option:(UIViewAnimationOptions)option
{
    [UIView animateWithDuration:secs delay:0.0 options:option
         animations:^{
             self.transform = CGAffineTransformRotate(self.transform, M_PI);
             self.alpha = self.alpha - 0.5;
         }
         completion:nil];
}

- (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option
{
    // first reduce the view to 1/100th of its original dimension
    CGAffineTransform trans = CGAffineTransformScale(view.transform, 0.01, 0.01);
    view.transform = trans; // do it instantly, no animation
    [self addSubview:view];
    // now return the view to normal dimension, animating this tranformation
    [UIView animateWithDuration:secs delay:0.0 options:option
        animations:^{
            view.transform = CGAffineTransformScale(view.transform, 100.0, 100.0);
        }
        completion:nil];    
}

- (void) removeWithZoomOutAnimation:(float)secs option:(UIViewAnimationOptions)option
{
    [UIView animateWithDuration:secs delay:0.0 options:option
    animations:^{
        self.transform = CGAffineTransformScale(self.transform, 0.1, 0.1);
    }
    completion:^(BOOL finished) { 
        [self removeFromSuperview]; 
    }];
}

// add with a fade-in effect
- (void) addSubviewWithFadeAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option
{
    view.alpha = 0.0;   // make the view transparent
    [self addSubview:view]; // add it
    [UIView animateWithDuration:secs delay:0.0 options:option
                     animations:^{view.alpha = 1.0;}
                     completion:nil];   // animate the return to visible 
}

// remove self making it "drain" from the sink!
- (void) removeWithSinkAnimation:(int)steps
{
    //NSTimer *timer;
    if (steps > 0 && steps < 100)   // just to avoid too much steps
        self.tag = steps;
    else
        self.tag = 50;
    [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(removeWithSinkAnimationRotateTimer:) userInfo:nil repeats:YES];
}
- (void) removeWithSinkAnimationRotateTimer:(NSTimer*) timer
{
    CGAffineTransform trans = CGAffineTransformRotate(CGAffineTransformScale(self.transform, 0.9, 0.9),0.314);
    self.transform = trans;
    self.alpha = self.alpha * 0.98;
    self.tag = self.tag - 1;
    if (self.tag <= 0)
    {
        [timer invalidate];
        [self removeFromSuperview];
    }
}

@end

我希望它能解决你的问题。享受:)