UIViewController 过渡在下拉手势关闭时闪烁

Posted

技术标签:

【中文标题】UIViewController 过渡在下拉手势关闭时闪烁【英文标题】:UIViewController transition flickers on dismissal with pull-down gesture 【发布时间】:2017-10-27 13:02:50 【问题描述】:

当用户使用自定义转换单击MKMapView 中的注释时,我正在呈现一个视图控制器。过渡动画显示的视图控制器的框架从注释的框架开始到其最终的全屏外观。

当关闭显示的视图控制器时,用户有两个选择:她可以单击右上角的关闭按钮,关闭转换会将视图动画返回到注释的框架。这部分工作正常。

但用户也可以将视图向下拖动至少 200 点,当她抬起手指时,我希望运行相同的关闭转换,但从“向下拖动”状态开始。

更详细地说,我呈现的视图控制器的根视图有两个子视图:一个我称之为contentView,它包含所有实际内容,一个定义了UIPanGestureRecognizer 并被移动根据用户的手势向下;还有一个我称之为pullProgressView 的,它位于contentView 的下方,并在用户拖动时保持在原位。它会显示一个圆圈,该圆圈会填满用户已经向下拖动的位置,以指示在哪个点松开手指会关闭视图控制器。

手势识别器的基本部分如下所示:

let progress = sender.translation(in: contentView).y
let screen = UIScreen.main.bounds

if sender.state == .began || sender.state == .changed 
    if progress > 0 
        // Dragged down -> allow movement of the view
        contentView.center = CGPoint(x: contentView.center.x,
                                     y: screen.size.height / 2 + progress)
    
 else if sender.state == .ended 
    if contentView.frame.origin.y > threshold 
        // Dragged down far enough to dismiss the view controller
        print("contentView frame right before dismissing: \(contentView.frame)")
        self.dismissView()
     else 
        // Not dragged down far enough, animate the view back
        // to its original position
        UIView.animate(withDuration: 0.3) 
            self.contentView.frame = screen
        
    

我调用 dismissView() 时接管的 animateTransition 方法包含以下代码:

let contentView = (transitionContext.viewController(forKey: .from) as! PresentedViewController).contentView!
print("contentView frame going into animateTransition: \(contentView.frame)")

问题在于,当我抬起手指将视图控制器向下拖动后将其关闭时,视图“闪烁”回其原始的未拖动状态。上述代码 sn-ps 中的两个 print 语句产生以下输出:

contentView frame right before dismissing: (0.0, 330.0, 375.0, 667.0)
contentView frame going into animateTransition: (0.0, 0.0, 375.0, 667.0)

所以contentView 的框架不会“存活”到animateTransition 方法中(注意y 参数)。我可以在animateTransition 中手动设置它,方法是向UIPanGestureRecognizer 询问其进度,这可行,但在contentView 移回其拖下的框架之前,仍然会出现难看的闪烁。

有人知道如何解决这个问题吗?还是解决这个问题的更好方法?我读过UIPercentDrivenInteractiveTransition,但它适用于我的情况吗?向下拖动手势并不会真正产生任何百分比的实际关闭动画(这会将帧变形回地图注释之一),所以我不知道如何使用UIPercentDrivenInteractiveTransition 解决问题。

【问题讨论】:

【参考方案1】:

我找到了一个使用视图控制器包含的不同解决方案。基本上,我将一个子视图控制器及其视图作为子视图添加到呈现视图控制器。此外,我将pullProgressView 添加为子视图控制器视图下方的子视图。

这样我就不必依赖过渡委托,而是可以在我完成所有动画后自己处理子视图控制器的解除。

【讨论】:

以上是关于UIViewController 过渡在下拉手势关闭时闪烁的主要内容,如果未能解决你的问题,请参考以下文章

UIPageViewController 从子 UIViewController 上的控制过渡

过渡到已经包含的 UIViewController

从 UIViewController 过渡到 TabBarViewController

带有旋转的自定义 UIViewController 过渡

在 2 个 UIViewController 的过渡之间为 UIView 元素设置动画

UIViewController 默认过渡动画不起作用