gpt4 book ai didi

ios - UICollectionViewController 的自定义弹出动画不起作用

转载 作者:行者123 更新时间:2023-11-28 08:38:25 27 4
gpt4 key购买 nike

我有一个名为 ProfileCollectionViewController 的 Collection View ,用于收集图像。单击图像时,它会显示一个全屏显示图像的 Horizo​​ntalProfileViewController。当在 Horizo​​ntalProfileViewController 上按下后退按钮时,我希望全屏图像动画回到 ProfileViewController 中的缩略图。我将选定的索引路径从 ProfileViewController 作为 initialIndexPath 传递给 Horizo​​ntalProfileViewController,以便知道缩略图的位置。下面是我的过渡动画代码

import UIKit

class SEHorizontalFeedToProfile: NSObject, UIViewControllerAnimatedTransitioning {

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.2
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

if let profileVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? SEProfileGridViewController, horizontalFeedVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? SEProfileHorizontalViewController, containerView = transitionContext.containerView() {
let duration = transitionDuration(transitionContext)
profileVC.collectionView?.reloadData()
if let indexPath = horizontalFeedVC.initialIndexPath {
let cell = profileVC.collectionView?.cellForItemAtIndexPath(indexPath)
print(indexPath)
let imageSnapshot = horizontalFeedVC.view.snapshotViewAfterScreenUpdates(false)
let snapshotFrame = containerView.convertRect(horizontalFeedVC.view.frame, fromView: horizontalFeedVC.view)
imageSnapshot.frame = snapshotFrame
horizontalFeedVC.view.hidden = true

profileVC.view.frame = transitionContext.finalFrameForViewController(profileVC)
containerView.insertSubview(profileVC.view, belowSubview: horizontalFeedVC.view)
containerView.addSubview(imageSnapshot)

UIView.animateWithDuration(duration, animations: {
var cellFrame = CGRectMake(0, 0, 0, 0)
if let theFrame = cell?.frame {
cellFrame = theFrame
}
let frame = containerView.convertRect(cellFrame, fromView: profileVC.collectionView)
imageSnapshot.frame = frame
}, completion: { (succeed) in
if succeed {
horizontalFeedVC.view.hidden = false
// cell.contentView.hidden = false
imageSnapshot.removeFromSuperview()
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
}
})
}
}
}

}

我下了断点,在代码中发现了这一点

let cell = profileVC.collectionView?.cellForItemAtIndexPath(indexPath)

单元格为零。我不明白为什么它会是零。请帮我。提前谢谢你。

profileVC 是 UICollectionViewController 的子类

PS:请查看以下执行完全相同操作且没有任何问题的项目。我试图模仿它,但它对我不起作用。 https://github.com/PeteC/InteractiveViewControllerTransitions

最佳答案

正如问题评论中指出的那样,单元格设置为 nil 因为该单元格不可见。由于您的 Horizo​​ntalProfileViewController 允许滚动到其他图片,因此可以滚动到尚未在您的 ProfileCollectionViewController 中为其创建 UICollectionViewCell 的图像。

您可以通过滚动到当前图像应该在 UICollectionView 上的位置来解决这个问题。你说 initialIndexPath 最初是第一个选择的图像的 indexPath。假设您在用户滚动到不同图像时更新它,以便它仍然准确地表示屏幕上图像的 indexPath,我们可以使用它来强制 UICollectionView 在必要时滚动到当前单元格。

通过对您的代码进行一些调整,这应该会给您带来预期的效果:

import UIKit    

class SEHorizontalFeedToProfile: NSObject, UIViewControllerAnimatedTransitioning {

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.2
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

if let profileVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? SEProfileGridViewController, horizontalFeedVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? SEProfileHorizontalViewController, containerView = transitionContext.containerView() {
let duration = transitionDuration(transitionContext)
//profileVC.collectionView?.reloadData() //Remove this

if let indexPath = horizontalFeedVC.initialIndexPath {
var cell = profileVC.collectionView?.cellForItemAtIndexPath(indexPath) //make cell a var so it can be reassigned if necessary
print(indexPath)

if cell == nil{ //This if block is added. Again it is crucial that initialIndexPath was updated as the user scrolled.
profileVC.collectionView?.scrollToItemAtIndexPath(horizontalFeedVC.initialIndexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredVertically, animated: false)
profileVC.collectionView?.layoutIfNeeded() //This is necessary to force the collectionView to layout any necessary new cells after scrolling
cell = profileVC.collectionView?.cellForItemAtIndexPath(indexPath)
}
let imageSnapshot = horizontalFeedVC.view.snapshotViewAfterScreenUpdates(false)
let snapshotFrame = containerView.convertRect(horizontalFeedVC.view.frame, fromView: horizontalFeedVC.view)
imageSnapshot.frame = snapshotFrame
horizontalFeedVC.view.hidden = true

profileVC.view.frame = transitionContext.finalFrameForViewController(profileVC)
containerView.insertSubview(profileVC.view, belowSubview: horizontalFeedVC.view)
containerView.addSubview(imageSnapshot)

UIView.animateWithDuration(duration, animations: {
var cellFrame = CGRectMake(0, 0, 0, 0)
if let theFrame = cell?.frame {
cellFrame = theFrame
}
let frame = containerView.convertRect(cellFrame, fromView: profileVC.collectionView)
imageSnapshot.frame = frame
}, completion: { (succeed) in
if succeed {
horizontalFeedVC.view.hidden = false
// cell.contentView.hidden = false
imageSnapshot.removeFromSuperview()
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
}
})
}
}
}

现在,如果当前的 UICollectionViewCell 尚未创建:

  1. 滚动使单元格的 indexPath 位于 View 的中心

  2. 强制 UICollectionView 布局其 subview ,创建任何必要的 UITableViewCells

  3. 再次请求 UITableViewCell,但这次它不应该是 nil

关于ios - UICollectionViewController 的自定义弹出动画不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37036001/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com