我创建了一个交互式过渡。我的func animateTransition(transitionContext: UIViewControllerContextTransitioning)
很正常,我拿到容器了UIView
,我将两个相加UIViewControllers
然后我在 a 中进行动画更改UIView.animateWithDuration(duration, animations, completion)
.
I add a UIScreenEdgePanGestureRecognizer
到我的UIViewController
。除非我进行非常快速的平移,否则效果很好。
在最后一种情况下,应用程序没有响应,仍然处于相同状态UIViewController
(转换似乎不起作用)但后台任务正在运行。当我运行Debug View Hierarchy
,我看到了新的UIViewController
而不是前一个,以及前一个(至少它的UIView
) 站在转换结束时应该所在的位置。
我做了一些打印和检查点,从中我可以说,当问题发生时,动画完成(我的那个animateTransition
方法)未达到,所以我不能调用transitionContext.completeTransition
完成或不完成转换的方法。
我也可以看到平底锅有时会从UIGestureRecognizerState.Began
直接到UIGestureRecognizerState.Ended
不经过UIGestureRecognizerState.Changed
.
当它经过的时候UIGestureRecognizerState.Changed
, both the translation
and the velocity
每个都保持相同UIGestureRecognizerState.Changed
states.
EDIT :
这是代码:
animateTransition
method
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
let containerView = transitionContext.containerView()
let screens: (from: UIViewController, to: UIViewController) = (transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!, transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!)
let parentViewController = presenting ? screens.from : screens.to
let childViewController = presenting ? screens.to : screens.from
let parentView = parentViewController.view
let childView = childViewController.view
// positionning the "to" viewController's view for the animation
if presenting {
offStageChildViewController(childView)
}
containerView.addSubview(parentView)
containerView.addSubview(childView)
let duration = transitionDuration(transitionContext)
UIView.animateWithDuration(duration, animations: {
if self.presenting {
self.onStageViewController(childView)
self.offStageParentViewController(parentView)
} else {
self.onStageViewController(parentView)
self.offStageChildViewController(childView)
}}, completion: { finished in
if transitionContext.transitionWasCancelled() {
transitionContext.completeTransition(false)
} else {
transitionContext.completeTransition(true)
}
})
}
手势和手势处理程序:
weak var fromViewController: UIViewController! {
didSet {
let screenEdgePanRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "presentingViewController:")
screenEdgePanRecognizer.edges = edge
fromViewController.view.addGestureRecognizer(screenEdgePanRecognizer)
}
}
func presentingViewController(pan: UIPanGestureRecognizer) {
let percentage = getPercentage(pan)
switch pan.state {
case UIGestureRecognizerState.Began:
interactive = true
presentViewController(pan)
case UIGestureRecognizerState.Changed:
updateInteractiveTransition(percentage)
case UIGestureRecognizerState.Ended:
interactive = false
if finishPresenting(pan, percentage: percentage) {
finishInteractiveTransition()
} else {
cancelInteractiveTransition()
}
default:
break
}
}
知道会发生什么吗?
EDIT 2:
以下是未公开的方法:
override func getPercentage(pan: UIPanGestureRecognizer) -> CGFloat {
let translation = pan.translationInView(pan.view!)
return abs(translation.x / pan.view!.bounds.width)
}
override func onStageViewController(view: UIView) {
view.transform = CGAffineTransformIdentity
}
override func offStageParentViewController(view: UIView) {
view.transform = CGAffineTransformMakeTranslation(-view.bounds.width / 2, 0)
}
override func offStageChildViewController(view: UIView) {
view.transform = CGAffineTransformMakeTranslation(view.bounds.width, 0)
}
override func presentViewController(pan: UIPanGestureRecognizer) {
let location = pan.locationInView((fromViewController as! MainViewController).tableView)
let indexPath = (fromViewController as! MainViewController).tableView.indexPathForRowAtPoint(location)
if indexPath == nil {
pan.state = .Failed
return
}
fromViewController.performSegueWithIdentifier("chartSegue", sender: pan)
}
- 我删除了“over”添加行 => 没有修复它
- I added
updateInteractiveTransition
in .Began
, in .Ended
,在两个 => 中都没有修复它
- 我在我的视图层上打开了shouldRasterize
toViewController
并让它一直开着 => 没有修复它
但问题是,为什么在做快速交互手势的时候,是不是响应不够快呢?
实际上,只要我的手指留得足够长,它就可以通过快速交互手势来工作。例如,如果我平移速度非常快,超过(比方说)1 厘米,那就没问题。如果我在小于 1 厘米的小表面(再说一遍)上快速平移,那就不行了
可能的候选者包括动画视图太复杂(或具有复杂的效果,如阴影)
我也想过一个复杂的观点,但我不认为我的观点真的很复杂。有一堆按钮和标签,自定义的UIControl
作为分段的片段,图表(在控制器出现后加载)和 xib 被加载到 viewController 内。
好的,我刚刚创建了一个project https://github.com/nico75005/testTransition使用最少的类和对象才能触发问题。因此,要触发它,您只需从右向左快速而短暂地滑动即可。
我注意到它第一次工作非常容易,但是如果你第一次正常拖动视图控制器,那么触发它会变得更加困难(甚至不可能?)。在我的完整项目中,这并不重要。