微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将自定义过渡目标设置为UICollectionReusableView不会设置动画,甚至不会调用

如何解决将自定义过渡目标设置为UICollectionReusableView不会设置动画,甚至不会调用

我试图按照本教程从collectionview创建自定义过渡。

https://medium.com/@tungfam/custom-uiviewcontroller-transitions-in-swift-d1677e5aa0bf

我想尝试一些不同的方法,所以我考虑在呈现的ViewController中使用另一个collectionview,所以我认为拥有图像和集合视图的理想方法是将图像放在collectionview标头中,请更正我如果我错了。

我对自定义过渡非常陌生,但是我认为问题与在didSelectItemAt函数中需要使用的transitioningDelegate有关。

func collectionView(_ collectionView: UICollectionView,didSelectItemAt indexPath: IndexPath) {
        guard let animal = dataSource?.itemIdentifier(for: indexPath) else { return }
        
        selectedCellImageViewSnapshot = selectedCell?.imageView.snapshotView(afterScreenUpdates: false)
        
        let vc = TestingViewController()
        
        vc.transitioningDelegate = self //I think the issue is here
        vc.modalPresentationStyle = .fullScreen
        vc.data = animal

        self.present(vc,animated: true,completion: nil)
        print("Trans2")
    }

我认为问题必须出在转任的代表身上。由于要动画的图像位于标题中,因此我将UIViewControllerAnimatedTransitioning中的所有目标都设置为Header而不是secondViewController,因为这是图像所在的位置。问题是标题没有成员“ transitioningDelegate”。

它会确实过渡到下一个视图,但是没有动画。 这是我为UIViewControllerAnimatedTransitioning做的事情:

final class Animator: NSObject,UIViewControllerAnimatedTransitioning {
    
    
    static let duration: TimeInterval = 0.3
    
    private let type: PresentationType
    private let firstViewController: CollectionViewController
    private let secondViewController: SectionHeader
    private var selectedCellImageViewSnapshot: UIView
    private let cellImageViewRect: CGRect
    
    
    
    init?(type: PresentationType,firstViewController: CollectionViewController,secondViewController: SectionHeader,selectedCellImageViewSnapshot: UIView) {
        
        self.type = type
        self.firstViewController = firstViewController
        self.secondViewController = secondViewController
        self.selectedCellImageViewSnapshot = selectedCellImageViewSnapshot
        
        guard let window = firstViewController.view.window ?? secondViewController.window,let selectedCell = firstViewController.selectedCell
            else { return nil }
        
        
        self.cellImageViewRect = selectedCell.imageView.convert(selectedCell.imageView.bounds,to: window)
    }
    
    
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return Self.duration
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        let containerView = transitionContext.containerView

        print("1")
        guard let toView = transitionContext.view(forKey: .to) else {
            transitionContext.completeTransition(false)
            return
        }
        containerView.addSubview(toView)

        guard let selectedCell = firstViewController.selectedCell,let window = firstViewController.view.window ?? secondViewController.window,let cellImageSnapshot = selectedCell.imageView.snapshotView(afterScreenUpdates: true),let controllerImageSnapshot = secondViewController.topImg.snapshotView(afterScreenUpdates: true)
            else {
                transitionContext.completeTransition(true)
                return
        }
        let isPresenting = type.isPresenting

        let backgroundView: UIView
        let fadeView = UIView(frame: containerView.bounds)
        fadeView.backgroundColor = secondViewController.backgroundColor


        if isPresenting {
            selectedCellImageViewSnapshot = cellImageSnapshot

            backgroundView = UIView(frame: containerView.bounds)
            backgroundView.addSubview(fadeView)
            fadeView.alpha = 0
        } else {
            backgroundView = firstViewController.view.snapshotView(afterScreenUpdates: true) ?? fadeView
            backgroundView.addSubview(fadeView)
        }

        toView.alpha = 0


        [backgroundView,selectedCellImageViewSnapshot,controllerImageSnapshot].forEach { containerView.addSubview($0) }

        let controllerImageViewRect = secondViewController.topImg.convert(secondViewController.topImg.bounds,to: window)

        

        [selectedCellImageViewSnapshot,controllerImageSnapshot].forEach {
            $0.frame = isPresenting ? cellImageViewRect : controllerImageViewRect

            $0.layer.cornerRadius = isPresenting ? 12 : 0
            $0.layer.masksToBounds = true
        }

        controllerImageSnapshot.alpha = isPresenting ? 0 : 1

        selectedCellImageViewSnapshot.alpha = isPresenting ? 1 : 0


        UIView.animateKeyframes(withDuration: Self.duration,delay: 0,options: .calculationModeCubic,animations: {
            UIView.addKeyframe(withRelativeStartTime: 0,relativeDuration: 1) {
                self.selectedCellImageViewSnapshot.frame = isPresenting ? controllerImageViewRect: self.cellImageViewRect
                controllerImageSnapshot.frame = isPresenting ? controllerImageViewRect : self.cellImageViewRect

                fadeView.alpha = isPresenting ? 1 : 0

                [controllerImageSnapshot,self.selectedCellImageViewSnapshot].forEach {
                    $0.layer.cornerRadius = isPresenting ? 0 : 12
                }
            }

            UIView.addKeyframe(withRelativeStartTime: 0,relativeDuration: 0.6) {
                self.selectedCellImageViewSnapshot.alpha = isPresenting ? 0 : 1
                controllerImageSnapshot.alpha = isPresenting ? 1 : 0
            }

        }) { (_) in
            self.selectedCellImageViewSnapshot.removeFromSuperview()
            controllerImageSnapshot.removeFromSuperview()

            backgroundView.removeFromSuperview()

            toView.alpha = 1
            print("2")
            transitionContext.completeTransition(true)
        }
    }
    
    
    
}

enum PresentationType {
    case present
    case dismiss
    
    var isPresenting: Bool {
        return self == .present
    }
}

我在animateTransition上放置了打印语句,但是没有一个调用,这意味着也没有调用它。我确实在viewDidLoad中设置了collectionView的委托,并且确实设置了navigationController,在这里,我知道它只是显示内容,而这正是我在这里显示内容

func animationController(forPresented presented: UIViewController,presenting: UIViewController,source: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        guard let firstViewController = presenting as? CollectionViewController,let secondViewController = presented as? SectionHeader,let selectedCellImageViewSnapshot = selectedCellImageViewSnapshot
            else { return nil }
        
        animator = Animator(type: .present,firstViewController: firstViewController,secondViewController: secondViewController,selectedCellImageViewSnapshot: selectedCellImageViewSnapshot)
        print("Animator: \(String(describing: animator))")
        
        return animator
    }

如果还有其他需要帮助的地方,请询问。 谢谢

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。