有时会需要自定义present或者navigation的transition特效,
这个时候就需要在UIViewControllerAnimatedTransitioning协议的animateTransition:方法中手动制作动画,
无论是navigation中的transition还是present时的transition,都有一个containerView来执行transition,
但在不同的情况下fromView和toView与containerView的图层结构大相径庭,它们是怎样一个结构?
在不同情况开发者如何管理fromView和toView的add和remove?
这里对这个两个问题做一个整理。
1.navigation
navigation的push时,假设当前在视图A,要push到视图B(container便是navigation的UIViewControllerWrapperView),fromView就是视图A,toView是视图B。(当然,在大部分情况下,container、A、B的size是一样大的,这里是为了方便看层次)
在animateTransition:开始时图层如上,此时开发者需要手动将视图B添加到container当中(此时就可以实施你的特效)。
添加上去之后涂层如下图:
在动画结束后调用transitionContext的completeTransition:方法,系统会自动移除视图A,调用完complete方法后试图如下视图A被移出屏幕:
pop时则相反,fromView是视图B,toView是视图A,在animateTransition:开始时图层如上,开发者需要手动把视图A添加到container中,动画结束后调用transitionContext的completeTransition:方法,系统会自动将视图B移出。
2.present
present的图层相对navigation的push要复杂一点,它有一个cover的模式,对视图的添加和移除也与navigatio的push/pop大相径庭。在present时,视图A同样需要手动添加到container中,关闭时,就是dismiss时,不需要对视图A和视图B进行remove的操作,只需要调用transitionContext的completeTransition系统就会自动移出视图A和container,并把视图A放置回原来的位置。
加下来就是present时的图层问题,presentationStyle目前有以下几种
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0, //normal
UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED, //over
UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED, //over
UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2), //normal
UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0), //over
UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0), //over
UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0), //over
UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED, //over
UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,
};
不同的style下,图层时不一样的,但目前总体来只有两种图层结构,normal和over两种结构,
我在上面对每种style的图层样式做了标示。
依旧是从视图A present 到视图B,当屏幕上只有视图A时图层结构图下:
UIview就是视图A
1.normal结构
present时,执行到animateTransition:时图层如下:
可以看到系统自动创建了一个UITransitionView,也就是transition的container,这个container取代了presentingViewController所属View(就是视图A)的位置,然后把视图A放到了container中,开发者需要做的操作就是把toView(视图B)放入container中,然后调用completeTransition(系统将自动把视图A移除)。
2.over结构
对比上面的normal结构来看,over结构下,container并没有取代原来视图A的位置,而是被add进了视图A的superView,并且覆盖在视图A的上面,开发者需要做的操作就是把toView(视图B)放入container中,然后调用completeTransition(系统不会把视图A移除)。