Nic*_*ico 5 uiviewcontroller ios swift
我创建了一个交互式过渡.我func animateTransition(transitionContext: UIViewControllerContextTransitioning)很正常,我得到了容器UIView,我添加了两个UIViewControllers,然后我做了动画更改UIView.animateWithDuration(duration, animations, completion).
我添加了一个UIScreenEdgePanGestureRecognizer来自我的UIViewController.它运作良好,除非我做一个非常快速的平底锅.
在最后一个场景中,应用程序没有响应,仍然是相同的UIViewController(转换似乎没有工作)但后台任务运行.当我运行时Debug View Hierarchy,我看到的是新的UIViewController而不是前一个,而前一个(至少是它UIView)代表它应该在转换结束时站立的位置.
我做了一些打印和检查点,从中我可以说,当问题发生时,动画的完成(我animateTransition方法中的那个)没有到达,所以我无法调用transitionContext.completeTransition方法来完成或不完成转换.
我也可以看到平底锅有时从UIGestureRecognizerState.Began直线走到UIGestureRecognizerState.Ended没经过UIGestureRecognizerState.Changed.
当它通过UIGestureRecognizerState.Changed,都将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)
}
})
}
Run Code Online (Sandbox Code Playgroud)
手势和手势处理程序:
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
}
}
Run Code Online (Sandbox Code Playgroud)
知道会发生什么吗?
编辑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)
}
Run Code Online (Sandbox Code Playgroud)
updateInteractiveTransition了.Beganin .Ended,in = =>没有修复它toViewController并且一直让它继续=>没有修复它但问题是,在进行快速交互式手势时,为什么它的响应速度不够快
只要我的手指足够长,它实际上可以使用快速交互式手势.例如,如果我在超过(比方说)1cm时非常快速地平移,那就没关系.如果我在小于1厘米的小表面(再说一次)上快速平移,那就不行了
可能的候选者包括动画的视图太复杂(或具有阴影等复杂效果)
我也想过一个复杂的观点,但我认为我的观点并不复杂.有一堆按钮和标签,一个自定义UIControl作为分段,一个图表(一旦控制器出现就加载)和一个xib加载到viewController中.
好的,我刚刚创建了一个包含MINIMUM类和对象的项目,以便触发问题.因此,要触发它,您只需从右向左快速轻扫即可.
我注意到它第一次很容易工作,但如果你第一次正常拖动视图控制器,那么触发它会更加困难(甚至不可能?).在我的完整项目中,它并不重要.
Rob*_*Rob 10
当我诊断出这个问题时,我注意到手势的变化和结束的状态事件都在发生之前animateTransition发生.所以动画在它开始之前就被取消/完成了!
我尝试使用GCD动画同步队列,以确保更新UIPercentDrivenInterativeTransition之前不会发生`animate:
private let animationSynchronizationQueue = dispatch_queue_create("com.domain.app.animationsynchronization", DISPATCH_QUEUE_SERIAL)
Run Code Online (Sandbox Code Playgroud)
然后,我有一个实用程序方法来使用此队列:
func dispatchToMainFromSynchronizationQueue(block: dispatch_block_t) {
dispatch_async(animationSynchronizationQueue) {
dispatch_sync(dispatch_get_main_queue(), block)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我的手势处理程序确保更改和结束状态通过该队列路由:
func handlePan(gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .Began:
dispatch_suspend(animationSynchronizationQueue)
fromViewController.performSegueWithIdentifier("segueID", sender: gesture)
case .Changed:
dispatchToMainFromSynchronizationQueue() {
self.updateInteractiveTransition(percentage)
}
case .Ended:
dispatchToMainFromSynchronizationQueue() {
if isOkToFinish {
self.finishInteractiveTransition()
} else {
self.cancelInteractiveTransition()
}
}
default:
break
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我有手势识别器的.Began状态暂停该队列,并且我让动画控制器恢复该队列animationTransition(确保只有在该方法运行之后,手势才会尝试更新UIPercentDrivenInteractiveTransition对象之前,队列才会再次启动.
| 归档时间: |
|
| 查看次数: |
3671 次 |
| 最近记录: |