我有以下设置:
红色 Controller 有一个方法
- (IBAction)unwindToRed:(UISegue *)segue
和一个
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
返回此事件的自定义转场。
在我的自定义 segue 中,执行代码中有以下内容:
- (void)perform
{
// Just helpers to get the controllers from the segue
UIViewController *destination = self.destinationViewController;
UIViewController *source = self.sourceViewController;
// Setting transitioning delegate for custom transitions
destination.transitioningDelegate = self;
source.transitioningDelegate = self;
destination.modalTransitionStyle = UIModalPresentationCustom;
source.modalPresentationStyle = UIModalPresentationCurrentContext;
// When I am transitioning to a new one
if(!self.reversed)
{
[source presentViewController:destination animated:YES completion:nil];
}
// Or reversing from a current one
else
{
[source dismissViewControllerAnimated:YES completion:nil];
}
}
如你所见,我已经设置了一个转换委托(delegate),它会依次调用
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
在我应用自定义动画的动画 Controller 上。但是现在当我在黄色 View 上点击 Unwind to Red 时,它只会“展开”到它的父级。 (例如蓝色的)。
当我将自定义 segue 排除在等式之外时,它工作得很好。它一直到顶部。
现在我认为这与
[source dismissViewControllerAnimated:YES];
行,因为这通常只是“向上”,我想我的问题是,我应该在那里称呼什么,以便在需要时一直上升到红色?黄色是模态叠加层。所以“pop too root”是行不通的。
最佳答案
指定自定义 Segue
解决方案是使用自定义 segue 来展开。 不幸的是,您不能像在普通转场中那样在界面构建器中为展开指定自定义转场。你必须用代码指定它。
UIViewController
上有一个函数,您可以覆盖它,称为 segueForUnwindingToViewController
,它指定要使用哪个 segue 进行展开。棘手的部分是知道要在哪个 View Controller 上覆盖此功能。答案是在您要转换到/从中转换的 View Controller 的父级上执行此操作。在我的例子中,它是 UINavigationController
。导航 Controller 是第一个和第三个 View Controller 的容器 View Controller 。如果我在我的 View 中嵌入了 subview Controller ,那么答案就不会是导航 Controller ,而是父 View Controller 。
通过继承 UINavigationController
创建自定义导航 Controller 。然后确保在界面生成器中设置导航 Controller 的自定义类。现在您可以覆盖 segueForUnwindingToViewController
函数。这是一个最小的实现。
class MyNavigationController: UINavigationController {
override func segueForUnwindingToViewController(toViewController: UIViewController,
fromViewController: UIViewController,
identifier: String?) -> UIStoryboardSegue {
return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController)
}
}
为自定义转场添加动画
override func segueForUnwindingToViewController(toViewController: UIViewController,
fromViewController: UIViewController,
identifier: String?) -> UIStoryboardSegue {
return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController) {
let fromView = fromViewController.view
let toView = toViewController.view
if let containerView = fromView.superview {
let initialFrame = fromView.frame
var offscreenRect = initialFrame
offscreenRect.origin.x -= CGRectGetWidth(initialFrame)
toView.frame = offscreenRect
containerView.addSubview(toView)
// Being explicit with the types NSTimeInterval and CGFloat are important
// otherwise the swift compiler will complain
let duration: NSTimeInterval = 1.0
let delay: NSTimeInterval = 0.0
let options = UIViewAnimationOptions.CurveEaseInOut
let damping: CGFloat = 0.5
let velocity: CGFloat = 4.0
UIView.animateWithDuration(duration, delay: delay, usingSpringWithDamping: damping,
initialSpringVelocity: velocity, options: options, animations: {
toView.frame = initialFrame
}, completion: { finished in
toView.removeFromSuperview()
if let navController = toViewController.navigationController {
navController.popToViewController(toViewController, animated: false)
}
})
}
}
}
关于ios - 自定义展开转场动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24530662/