【发布时间】:2015-07-17 00:26:43
【问题描述】:
我创建了一个交互式过渡。我的func animateTransition(transitionContext: UIViewControllerContextTransitioning) 很正常,我得到容器UIView,添加两个UIViewControllers,然后在UIView.animateWithDuration(duration, animations, completion) 中进行动画更改。
我从UIViewController 向我的UIScreenEdgePanGestureRecognizer 添加了一个UIScreenEdgePanGestureRecognizer。它工作得很好,除非我做一个非常快速的平底锅。
在最后一种情况下,应用程序没有响应,仍然在同一 UIViewController 上(转换似乎没有工作)但后台任务运行。当我运行Debug View Hierarchy 时,我看到的是新的UIViewController 而不是之前的UIViewController,而之前的UIView 位于过渡结束时它应该位于的位置。
我做了一些打印和检查点,我可以说当问题发生时,动画完成(我的animateTransition方法中的那个)没有达到,所以我无法调用transitionContext.completeTransition 方法来完成或不完成过渡。
我还可以看到,平底锅有时会从 UIGestureRecognizerState.Began 直接转到 UIGestureRecognizerState.Ended 而没有经过 UIGestureRecognizerState.Changed。
当它通过UIGestureRecognizerState.Changed 时,both translation 和 velocity 对于每个UIGestureRecognizerState.Changed 状态都保持不变。
编辑:
代码如下:
animateTransition方法
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
}
}
知道会发生什么吗?
编辑 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”添加行 => 没有修复它
- 我在
.Began和.Ended中都添加了updateInteractiveTransition=> 没有修复它 - 我在
toViewController的视图层上打开了 shouldRasterize 并一直打开它 => 没有修复它
但问题是,为什么在做快速交互手势时反应不够快
只要我的手指离开的时间足够长,它实际上就可以使用快速交互手势。例如,如果我在超过(比方说)1cm 上快速平移,没关系。如果我在小于 1 厘米的小表面(再说一遍)上快速平移是不行的
可能的候选包括动画视图过于复杂(或具有复杂的效果,如阴影)
我也想过一个复杂的观点,但我不认为我的观点真的很复杂。有一堆按钮和标签,一个自定义的UIControl 充当分段段,一个图表(一旦控制器出现就加载)和一个 xib 在 viewController 内加载。
好的,我刚刚创建了一个带有 MINIMUM 类和对象的project,以触发问题。因此,要触发它,您只需从右向左快速而简短地滑动即可。
我注意到它第一次很容易工作,但如果你第一次正常拖动视图控制器,那么触发它会变得更加困难(甚至不可能?)。在我的完整项目中,这并不重要。
【问题讨论】:
-
@Rob 我尝试了所有方法,但都没有解决问题。唯一没问题的时候是 ToViewController 几乎是空的。我通过链接到触发问题的最小项目更新了问题。感谢您的帮助。
-
@Rob 你是在模拟器上还是在设备上试过?供您参考,在模拟器上,即使使用完整的项目,我也无法重现它。我正在使用我的 iphone 6 和最新版本的 iOS
-
好的,再次感谢您抽出宝贵的时间。我也注意到了别的东西。如果您尝试呈现 toViewController 并取消转换,则不会取消初始化该对象。下次您呈现任何视图控制器时,它将被取消初始化(即使您调用相同的视图控制器)。
标签: ios swift uiviewcontroller