运行视图控制器自定义转换后,视图控制器停止响应(但应用程序不会完全崩溃)

时间:2018-02-06 09:12:40

标签: ios swift uiview uiviewcontroller uiscrollview

我有两个视图控制器,从第一个我用模态segue显示第二个,显示样式设置为over current context。我也使用在过渡期间出现的模糊效果并在之后消失。 我已经创建了一个演示应用来展示过渡的样子:

enter image description here

此处,第二个视图控制器包含UIScrollView,并且在其上方有一个黄色矩形,另一个是UIView,上面有UIButtonUIButton也关闭了视图控制器。另外,正如您所看到的,我已将背景颜色设置为clear,因此可以看到模糊效果。

现在,在我的项目中,转换基本相同,除了我的视图控制器更重"。 第一个视图控制器嵌入在UINavigationController"UITabBarController内部,在其上我有一个自定义分段控件 由UIViewUIButton s以及带有自定义单元格的UITableView制作。 第二个视图控制器由UIScrollViewUIView组成(如上图所示,稍微大一点)。 view包含UIImageViewUILabel和较小的UIView,用作关闭视图的按钮。

这是我用来关闭第二个视图控制器的代码(UIScrollViewDelegate的方法)。

extension AuthorInfoViewController: UIScrollViewDelegate {
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    isDragging = true
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard isDragging else {
        return
    }

    if !isDismissingAuthorInfo && scrollView.contentOffset.y < -30.0 && dismissAnimator != nil {
        authoInfoViewControllerDelegate?.authorInfoViewControllerWillDismiss()
        isDismissingAuthorInfo = true
        dismissAnimator?.wantsInteractiveStart = true
        dismiss(animated: true, completion: nil)
        return
    }

    if isDismissingAuthorInfo {
        let progress = max(0.0, min(1.0, ((-scrollView.contentOffset.y) - 30) / 90.0))
        dismissAnimator?.update(progress)
    }
}

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let progress = max(0.0, min(1.0, ((-scrollView.contentOffset.y) - 30) / 90.0))

    if progress > 0.5 {
        dismissAnimator?.finish()
    } else {
        dismissAnimator?.cancel()
        print("Canceled")
    }

    isDismissingAuthorInfo = false
    isDragging = false
}
}

此处,isDismissingAuthorInfoisDragging是保留的布尔值 跟踪视图是否正在消失并被拖动。 authorInfoViewControllerWillDismiss是在符合第一个视图控制器的协议中实现的方法。该方法调用另一种方法,将模糊动画添加到自定义过渡动画师。

已编辑

动画师代码如下:

class DismissAnimator: UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning  {

var auxAnimationsForBlur: (()->Void)?
var auxAnimationsForTabBar: (()->Void)?
var auxAnimationsCancelForBlur: (()->Void)?
var auxAnimationsCancelForTabBar: (()->Void)?
var tabBar: UITabBar?
var blurView: UIView?


let transitionDuration = 0.75


func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {

    return transitionDuration
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    transitionAnimator(using: transitionContext).startAnimation()
}

func transitionAnimator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating {

    let duration = transitionDuration(using: transitionContext)

    let container = transitionContext.containerView
    let from = transitionContext.view(forKey: .from)!

    container.addSubview(from)

    let animator = UIViewPropertyAnimator(duration: duration, curve: .easeOut)

    animator.addAnimations({
        from.transform = CGAffineTransform(translationX: 0.0, y: container.frame.size.height + 30)
    }, delayFactor: 0.15)

    animator.addCompletion { (position) in
        switch position {
        case .end:
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
            self.tabBar?.isHidden = false 
            self.blurView?.removeFromSuperview()
        default:
            transitionContext.completeTransition(false)
            self.auxAnimationsCancelForBlur?()
            self.auxAnimationsCancelForTabBar?()
        }

    }

    if let auxAnimationsForBlur = auxAnimationsForBlur {
        animator.addAnimations(auxAnimationsForBlur)
    }

    if let auxAnimationsForTabBar = auxAnimationsForTabBar {
        animator.addAnimations(auxAnimationsForTabBar)
    }

    return animator

}

func interruptibleAnimator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating {
    return transitionAnimator(using:transitionContext)
  } 
}

在上面的代码中,auxAnimationsForBlur用于向动画师添加模糊动画,auxAnimationsCancelForBlur用于取消动画,auxAnimationsForTabBar用于添加动画alphatabBarauxAnimationsCancelForTabBar用于取消它。

现在,问题如下:动画工作正常,但是在通过拖动第二个视图控制器多次(5-9,大约)运行它之后,在转换结束并显示第一个视图控制器之后,它只是停止响应。但是,在底部我有一个tab bar,它可以工作。因此,当我切换到另一个选项卡并返回时,我看到第二个视图控制器和它后面的黑屏(第一个视图控制器应该在哪里)。发生这种情况时,cancel上的UIPercentDrivenInteractiveTransition方法会从上面的scrollViewWillEndDragging方法调用(在控制台上我会看到打印出来的cancel)。 cancel UIPercentDrivenInteractiveTransition上的interruptibleAnimator(using:)方法是否可能导致此问题,因为当我注释掉该方法的调用时,似乎一切正常(在这种情况下,我也会注释掉)在我的动画师上调用print(Xtrain['Sex'].head().tolist()) 方法,所以我失去了过渡的交互行为)?通过点击关闭按钮关闭第二个视图控制器时,我无法重现此行为,所以我认为它与拖动有关。

什么可能导致这个问题,你有什么建议解决它?我非常感谢你的帮助。

0 个答案:

没有答案