我正在尝试构建一个自定义视图控制器过渡,该过渡与这些API交互且可中断:
我想要实现的是,我可以模态呈现视图控制器,然后使用UIPanGestureRecognizer
通过向下拖动来关闭呈现的视图控制器。如果我在屏幕的上半部分放开手指,则应取消过渡,否则过渡将成功完成。
以下是有关该问题的代码:
func handlePanGesture(gestureRecognizer: UIPanGestureRecognizer) {
let translation = gestureRecognizer.translation(in: presentedViewController.view)
switch gestureRecognizer.state {
case .began:
interacting = true
presentingViewController.dismiss(animated: true) {
print("Dismissal Completion Callback is Called.")
// How can I know the dismissal is successful or cancelled.
}
case .changed:
let fraction = (translation.y / UIScreen.main.bounds.height)
update(fraction)
case .ended, .cancelled:
interacting = false
if (percentComplete > 0.5) {
finish()
} else {
cancel()
}
default:
break
}
}
我的代码在UI和交互方面表现出色,但我不了解函数func dismiss(animated flag: Bool, completion: (() -> Void)? = nil)
的行为。
在.began
的{{1}}情况下,将调用Pan Gesture
,因此自定义过渡开始。但是presentingViewController.dismiss(animated: true) { ... }
回调始终被称为“无”,解雇转换是否被取消。
我观看了WWDC的这些视频:
他们使用示例代码来演示如何通过UINavigationController进行自定义转换,并且没有提及解雇回调。
completion
在有关presentingViewController.dismiss(animated: true) {
debugPrint("Dismissal Completion Called")
debugPrint("[ presentedViewController.transitionCoordinator?.isCancelled \(self.presentedViewController.transitionCoordinator?.isCancelled) ]")
}
参数的文档中:
完成
关闭视图控制器后要执行的块。该块没有返回值,并且不带参数。您可以为此参数指定nil。
completion
的真正含义是什么,因为它总是在取消或结束自定义转换后才调用?
当我使用自定义过渡进行演示和解雇时,处理真正的解雇完成以更新UI和数据的最佳实践是什么?
答案 0 :(得分:0)
经过一些研究和测试-是的,我想这有点令人困惑。
关闭VC后,将调用 NOT (完成)块。而是在函数返回后称为 。
因此,假设您正在实现UIPercentDrivenInteractiveTransition
,.dismiss()
会触发您的过渡代码,并在您cancel()
或finish()
时返回-但其完成块不了解您实际上对过渡做了什么。
我敢肯定有多种解决方法...但是我的第一个想法是将您的“完成代码”放在case .ended, .cancelled:
中,您已经(已经)确定是否删除VC (无论是致电.cancel()
还是.finish()
)。
答案 1 :(得分:0)
最后,我在Apple文档中发现了一些有用的东西
在过渡动画结束时,至关重要的是调用
completeTransition:
方法。调用该方法将告诉UIKit过渡已完成,并且用户可以开始使用显示的视图控制器。调用该方法还会触发一系列其他完成处理程序,包括presentViewController:animated:completion:方法中的一个和动画师对象自己的animationEnded:方法中的一个。调用completeTransition:方法的最佳位置是动画块的完成处理程序中。由于可以取消转换,因此应该使用上下文对象的transitionWasCancelled方法的返回值来确定需要进行的清理。取消演示后,动画设计师必须撤消对视图层次结构所做的任何修改。成功解雇需要采取类似的行动。
因此present(_:animated:completion:)
和dismiss(animated:completion:)
的完成回调没有任何参数来指示转换是完成还是取消。如果在完成转换或取消转换时调用transitionContext.completeTransition(_:)
方法,它们都将被调用。这种行为是故意设计的。