我想制作像iOS主屏幕文件夹这样的动画。我在主视图控制器和容器视图中有一个容器视图我在两个带有动画的视图控制器之间切换 以下是主视图控制器类的代码:
class MainContainerViewController: UIViewController {
@IBOutlet weak var containerView: UIView!
let duration = 1.0
var presenting = true
var originFrame = CGRect.zero
var indexPathSelectedCell: IndexPath?
var dismissCompletion: (()->())?
func cycle(fromViewController: UIViewController, toViewController: UIViewController) {
let folderViewC = (presenting ? fromViewController : toViewController) as! ViewController
let projectViewC = (presenting ? toViewController : fromViewController) as! ProjectViewController
let cellView = (presenting ? (folderViewC.folderCollectionView.cellForItem(at: folderViewC.folderCollectionView.indexPathsForSelectedItems!.first!) as! FolderCollectionViewCell).folderView : projectViewC.containerView)!
let cellSnapshot = cellView.snapshotView(afterScreenUpdates: false)!
let cellFrame = containerView.convert(cellView.frame, from: cellView.superview)
cellSnapshot.frame = cellFrame
cellView.isHidden = true
toViewController.view.frame = self.containerView.frame
toViewController.view.layoutIfNeeded()
toViewController.view.alpha = 0
presenting ? (projectViewC.containerView.isHidden = true) : ((folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.isHidden = true)
fromViewController.willMove(toParentViewController: nil)
self.addChildViewController(toViewController)
self.containerView.addSubview(toViewController.view)
self.containerView.addSubview(cellSnapshot)
UIView.animate(withDuration: duration, animations: {
toViewController.view.alpha = 1.0
let finalFrame = self.presenting ? projectViewC.containerView.frame : self.containerView.convert((folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.frame, from: (folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.superview)
cellSnapshot.frame = finalFrame
}) { (_) in
if !self.presenting {
self.dismissCompletion?()
}
self.presenting ? (projectViewC.containerView.isHidden = false) : ((folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.isHidden = false)
cellSnapshot.removeFromSuperview()
fromViewController.view.removeFromSuperview()
fromViewController.removeFromParentViewController()
toViewController.didMove(toParentViewController: nil)
}
}
}
除了将let finalFrame = self.presenting ? projectViewC.containerView.frame : self.containerView.convert((folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.frame, from: (folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.superview)
设置为错误值的finalFrame
之外,所有代码都能正常运行:
let finalFrame = self.presenting ? projectViewC.containerView.frame : self.containerView.convert((folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.frame, from: (folderViewC.folderCollectionView.cellForItem(at: self.indexPathSelectedCell!) as! FolderCollectionViewCell).folderView.superview)
行以这种方式运作:
答案 0 :(得分:3)
由于您在projectViewController中使用自动布局作为containerView的大小,因此您需要在代码的这一部分之后在layoutIfNeeded()
上调用self.containerView
:
self.addChildViewController(toViewController) self.containerView.addSubview(toViewController.view) self.containerView.addSubview(cellSnapshot)
所以它变成了:
self.addChildViewController(toViewController)
self.containerView.addSubview(toViewController.view)
self.containerView.addSubview(cellSnapshot)
self.containerView.layoutIfNeeded()