返回过渡时出现黑边

时间:2017-05-07 16:51:56

标签: swift transition uicollectionviewcell

我已实施以下动画过渡:

class PopInAndOutAnimator: NSObject, UIViewControllerAnimatedTransitioning {

fileprivate let _operationType : UINavigationControllerOperation
fileprivate let _transitionDuration : TimeInterval

init(operation: UINavigationControllerOperation) {
    _operationType = operation
    _transitionDuration = 0.4
}

init(operation: UINavigationControllerOperation, andDuration duration: TimeInterval) {
    _operationType = operation
    _transitionDuration = duration
}

//MARK: Push and Pop animations performers
internal func performPushTransition(_ transitionContext: UIViewControllerContextTransitioning) {

    guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else {
        // Something really bad happend and it is not possible to perform the transition
        print("ERROR: Transition impossible to perform since either the destination view or the conteiner view are missing!")
        return
    }

    let container = transitionContext.containerView

    guard let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as? CollectionPushAndPoppable,
        let fromView = fromViewController.collectionView,
        let currentCell = fromViewController.sourceCell else {
            // There are not enough info to perform the animation but it is still possible
            // to perform the transition presenting the destination view
            container.addSubview(toView)
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
            return
    }

    // Add to container the destination view
    container.addSubview(toView)

    // Prepare the screenshot of the destination view for animation
    let screenshotToView =  UIImageView(image: toView.screenshot)
    // set the frame of the screenshot equals to the cell's one
    screenshotToView.frame = currentCell.frame
    // Now I get the coordinates of screenshotToView inside the container
    let containerCoord = fromView.convert(screenshotToView.frame.origin, to: container)
    // set a new origin for the screenshotToView to overlap it to the cell
    screenshotToView.frame.origin = containerCoord

    // Prepare the screenshot of the source view for animation
    let screenshotFromView = UIImageView(image: currentCell.screenshot)
    screenshotFromView.frame = screenshotToView.frame

    // Add screenshots to transition container to set-up the animation
    container.addSubview(screenshotToView)
    container.addSubview(screenshotFromView)

    // Set views initial states
    toView.isHidden = true
    screenshotToView.isHidden = true

    // Delay to guarantee smooth effects
    let delayTime = DispatchTime.now() + Double(Int64(0.08 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    DispatchQueue.main.asyncAfter(deadline: delayTime) {
        screenshotToView.isHidden = false
    }

    UIView.animate(withDuration: _transitionDuration, delay: 0, usingSpringWithDamping: 0, initialSpringVelocity: 0, options: [], animations: { () -> Void in

        screenshotFromView.alpha = 0.0
        screenshotToView.frame = UIScreen.main.bounds
        screenshotToView.frame.origin = CGPoint(x: 0.0, y: 0.0)
        screenshotFromView.frame = screenshotToView.frame

    }) { _ in

        screenshotToView.removeFromSuperview()
        screenshotFromView.removeFromSuperview()
        toView.isHidden = false
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)

    }
}

internal func performPopTransition(_ transitionContext: UIViewControllerContextTransitioning) {

    guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else {
        // Something really bad happend and it is not possible to perform the transition
        print("ERROR: Transition impossible to perform since either the destination view or the conteiner view are missing!")
        return
    }

    let container = transitionContext.containerView

    guard let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as? CollectionPushAndPoppable,
        let toCollectionView = toViewController.collectionView,
        let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
        let fromView = fromViewController.view,
        let currentCell = toViewController.sourceCell else {
            // There are not enough info to perform the animation but it is still possible
            // to perform the transition presenting the destination view
            container.addSubview(toView)
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
            return
    }

    // Add destination view to the container view
    container.addSubview(toView)

    // Prepare the screenshot of the source view for animation
    let screenshotFromView = UIImageView(image: fromView.screenshot)
    screenshotFromView.frame = fromView.frame

    // Prepare the screenshot of the destination view for animation
    let screenshotToView = UIImageView(image: currentCell.screenshot)
    screenshotToView.frame = screenshotFromView.frame

    // Add screenshots to transition container to set-up the animation
    container.addSubview(screenshotToView)
    container.insertSubview(screenshotFromView, belowSubview: screenshotToView)

    // Set views initial states
    screenshotToView.alpha = 0.0
    fromView.isHidden = true
    currentCell.isHidden = true

    let containerCoord = toCollectionView.convert(currentCell.frame.origin, to: container)

    UIView.animate(withDuration: _transitionDuration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0, options: [], animations: { () -> Void in

        screenshotToView.alpha = 1.0
        screenshotFromView.frame = currentCell.frame
        screenshotFromView.frame.origin = containerCoord
        screenshotToView.frame = screenshotFromView.frame

    }) { _ in

        currentCell.isHidden = false
        screenshotFromView.removeFromSuperview()
        screenshotToView.removeFromSuperview()
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)

    }
}

//MARK: UIViewControllerAnimatedTransitioning
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return _transitionDuration
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    if _operationType == .push {
        performPushTransition(transitionContext)
    } else if _operationType == .pop {
        performPopTransition(transitionContext)
    }
}
}

我遇到的问题是我的集合视图单元格何时返回。在细胞底部有黑线的情况下会有一个小延迟。我不确定如何消除延迟或使该线变白以使其不明显。

0 个答案:

没有答案