更新于 04/2016:只是想更新一下,感谢大家的所有投票。请注意,这篇文章最初是在ARC、约束之前写的...还有很多其他新技术!所以在决定是否使用这些技术时,请考虑这一点。可能会有更现代的方法。噢,如果你发现了一种更好的方法,请回复一下让大家都看到。谢谢!
随后的一段时间...
经过大量研究,我找到了两个可行的解决方案。这两个方案都可以实现选项卡之间的动画切换。
方案1:从视图中转换(简单)
这是最简单的方法,利用了预定义的UIView转换方法。使用此解决方案时,我们无需管理视图,因为该方法会为我们完成工作。
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
[UIView transitionFromView:fromView
toView:toView
duration:0.5
options:(controllerIndex > tabBarController.selectedIndex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
completion:^(BOOL finished) {
if (finished) {
tabBarController.selectedIndex = controllerIndex;
}
}];
解决方案2:滚动(更复杂)
这是一个更复杂的解决方案,但可以更好地控制动画。在这个示例中,我们使视图滑入和滑出。使用这种方法需要自己管理视图。
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
CGRect viewSize = fromView.frame;
BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;
[fromView.superview addSubview:toView];
toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y, 320, viewSize.size.height);
[UIView animateWithDuration:0.3
animations: ^{
fromView.frame =CGRectMake((scrollRight ? -320 : 320), viewSize.origin.y, 320, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
}
completion:^(BOOL finished) {
if (finished) {
[fromView removeFromSuperview];
tabBarController.selectedIndex = controllerIndex;
}
}];
这是Swift语言的解决方案:
extension TabViewController: UITabBarControllerDelegate {
public func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let fromView: UIView = tabBarController.selectedViewController!.view
let toView : UIView = viewController.view
if fromView == toView {
return false
}
UIView.transitionFromView(fromView, toView: toView, duration: 0.3, options: UIViewAnimationOptions.TransitionCrossDissolve) { (finished:Bool) in
}
return true
}
}