动画期间帧值错误

时间:2016-08-18 15:12:39

标签: ios swift animation frame uicontainerview

我想制作像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)行以这种方式运作:

  • 检查是否正在展示
  • 如果它正在显示将常量设置为最终文件夹视图的 frame
  • 如果它被解雇,则从此folderView的超级视图转换所选Collection View Cell的folderView的 frame

以下是整个项目:https://github.com/ale00/OnteamAnon

1 个答案:

答案 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()