如何解决将自定义过渡目标设置为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 举报,一经查实,本站将立刻删除。