VCTransitionsLibrary を少し修正

VCTransitionsLibrary の肝は iOS 7 から使えるようになった UIPercentDrivenInteractiveTransition クラスと UIViewControllerAnimatedTransitioning プロトコル
この2つを上手に組み合わせて ViewController 間の遷移を行なっている。
(というわけで、実際には Tab間の遷移をスワイプでできるようにする用途のライブラリではない…)


のだけど、実際に使ってみると幾つかおかしな部分があったので修正を加えてある。


スワイプの動作が最初のタブ(View)でしか効かない
最初のタブから次のタブへスワイプで移動できるけど、移動先のタブからその先、もしくは戻ってくるスワイプが効かない。
ただし、タブバーでタブを選択してタブ間の移動を行なうと、移動した先から別のタブへのスワイプは効く。
なんとなくスワイプで移動した場合には移動先の ViewController でジェスチャーが効いてないんじゃないかな?と思ったのだけど、GitHub にある修正を行なったらちゃんと動作するようになった。

これでこの問題は解決!


スワイプの向きが反対になることがある
良くあるのが、最初のタブから次のタブへ遷移して、更に先へ行こうとすると逆に元に戻っちゃう。
これも GitHub で報告されているコードを加えたら問題が起きなくなった。

具体的には CEHorizontalSwipeInteractionController.m をこんな感じに。

- (void)handleGesture:(UIPanGestureRecognizer*)gestureRecognizer {
    CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view.superview];
    CGPoint vel = [gestureRecognizer velocityInView:gestureRecognizer.view];

    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan: {
            BOOL rightToLeftSwipe = vel.x < 0;


移動先が NavigationController の画面の場合、Fold のアニメーション中の画面はステータスバーが含まれていない状態なのでアニメーション終了時に画面全体がステータスバーの分だけ下にピョコっと下がる
これはとっても気持ちが悪い…。
VCTransitionsLibrary では遷移のアニメーションを作る際に遷移先の画像を作成するのだけど、ここで使っている -(UIView *)resizableSnapshotViewFromRect: afterScreenUpdates: withCapInsets: で得られる画像にはステータスバーが入っていない。なので、アニメーション中の画像はステータスバーがない状態(上に詰まった状態)で表示されてしまう。


どうしたらステータスバーが入った状態の画像を得られるのかわからなかったので(なんとなくIBでの設定とかでなんとかなりそうな気もするのだけど…)、今回は強引にこの部分を書き換えてしまった。
具体的には、遷移先の View が NavigationBar を持っていたらスナップショット作成するときにステータスバーの分だけ下に貼付けるようにした。
これだけではステータスバーの部分が黒くなってしまうので、snapshotView の background を NavigationBar.barTintColor もしくは白で塗りつぶしておく。


CEFoldAnimationController.m の 142行目以降をこんな感じに。

NSArray * subViews = view.subviews;
BOOL haveNavigationBar = NO;
UIColor *bgColor;

for (UIView *aView in subViews) {
	if ([aView isMemberOfClass:[UINavigationBar class]]) {
		haveNavigationBar = YES;
		bgColor = ((UINavigationBar *)aView).barTintColor;
		if (bgColor==nil) {
			bgColor = [UIColor whiteColor];
		}
	}
}

if (haveNavigationBar) {
	snapshotView.backgroundColor = bgColor;
	snapshotRegion = CGRectMake(offset, -20.0, foldWidth, size.height-20.0);
}
else {
	snapshotView.backgroundColor = view.backgroundColor;
	snapshotRegion = CGRectMake(offset, 0.0, foldWidth, size.height);
}

これで、先の動画のような動きをするようになった。