自定义视图过渡(如新的App Store)
现在,我已经完成了故事板的设置,我创建了一个名为PokemonCell的新文件,并将其设置如下:
导入UIKit
类PokemonCell:UICollectionViewCell {
@IBOutlet弱var pokemonNameLabel:UILabel!
@IBOutlet弱var pokemonImage:UIImageView!
func updateWithImage(image:UIImage?){
如果让imageToDisplay = image {
pokemonImage.image = imageToDisplay
}其他{
pokemonImage.image =无
}
}
覆盖func awakeFromNib(){
super.awakeFromNib()
updateWithImage(image:nil)
}
覆盖func prepareForReuse(){
super.prepareForReuse()
updateWithImage(image:nil)
}
}
连接您的插座,并将收集单元设置为PokemonCell。 在ViewController.swift文件中,设置数据源和集合视图的委托:
collectionView.dataSource =自我
collectionView.delegate =自我
并设置您的DataSource和Delegate方法:
扩展ViewController:UICollectionViewDataSource {
func numberOfSections(在collectionView:UICollectionView中)-> Int {
返回1
}
func collectionView(_ collectionView:UICollectionView,numberOfItemsInSection部分:Int)-> Int {
返回myPokemon.count
}
func collectionView(_ collectionView:UICollectionView,cellForItemAt indexPath:IndexPath)-> UICollectionViewCell {
让pokemonCell = collectionView.dequeueReusableCell(withReuseIdentifier:“ pokemonCell”,for:indexPath)为! 宠物小精灵细胞
pokemonCell.pokemonNameLabel.text = myPokemon [indexPath.row] .pokemonName
pokemonCell.updateWithImage(图像:UIImage(名称:myPokemon [indexPath.row] .pokemonImage))
返回pokemonCell
}
}
扩展ViewController:UICollectionViewDelegate {
}
现在已完成所有设置,在Main.storyboard设置中创建一个新的ViewController,其中包含一些值以捕获您的神奇宝贝数据,我的最终结果如下所示:
创建一个新的DetailViewController以使用您的集合视图信息:
导入UIKit
类DetailViewController:UIViewController {
@IBOutlet弱var pokemonDetailLabel:UILabel!
@IBOutlet弱var pokemonNameLabel:UILabel!
@IBOutlet弱var pokemonImageView:UIImageView!
var pokemonName:字符串=“”
var pokemonDetails:String =“”
var pokemonImageName:String =“”
覆盖func viewDidLoad(){
super.viewDidLoad()
view.addGestureRecognizer(UITapGestureRecognizer(target:self,action:#selector(actionClose(_ :))))
pokemonNameLabel.text = pokemonName
pokemonDetailLabel.text =宠物小精灵详细信息
pokemonImageView.image = UIImage(名称:pokemonImageName)
}
@objc func actionClose(_ tap:UITapGestureRecognizer){
presentingViewController?.dismiss(动画:true,完成:nil)
}
}
好的,现在我们可以开始实际开始本博客文章的主题! 好吧,我会说实话,在这一点上我已经完全迷路了。 我已经准备好了所有这些好的设置,但是不知道如何弄清楚从哪里开始。 幸运的是,我知道它与转换视图有关,因此我在Google上进行了快速搜索,并发现了该帖子https://www.raywenderlich.com/146692/ios-animation-tutorial-custom-view-controller-presentation-transitions- 2
按照它的指导,我创建了TransitionAnimator.swift文件:
导入UIKit
类TransitionAnimator:NSObject,UIViewControllerAnimatedTransitioning {
令durationExpanding = 0.75
让durationClosing = 0.5
var presenting = true
var originFrame = CGRect.zero
var dismissCompletion:(()-> Void)?
func transitionDuration(使用transitionContext:UIViewControllerContextTransitioning?)-> TimeInterval {
如果出示{
返回持续时间
}
返回持续时间
}
func animateTransition(使用transitionContext:UIViewControllerContextTransitioning){
让containerView = transitionContext.containerView
守护让toView = transitionContext.view(forKey:.to),让detailView =呈现? toView:transitionContext.view(forKey:.from)else {
返回
}
让initialFrame =呈现吗? originFrame:detailView.frame
让finalFrame =呈现吗? detailView.frame:originFrame
让xScaleFactor =呈现? initialFrame.width / finalFrame.width:finalFrame.width / initialFrame.width
让yScaleFactor =呈现? initialFrame.height / finalFrame.height:finalFrame.height / initialFrame.height
让scaleTransform = CGAffineTransform(scaleX:xScaleFactor,
y:yScaleFactor)
如果出示{
detailView.transform = scaleTransform
detailView.center = CGPoint(x:initialFrame.midX,y:initialFrame.midY)
detailView.clipsToBounds = true
}
containerView.addSubview(toView)
containerView.bringSubview(toFront:detailView)
如果出示{
//更新开始动画
UIView.animate(withDuration:durationExpanding,delay:0.0,
usingSpringWithDamping:1.0,initialSpringVelocity:0.0,//给它一些反弹,使过渡看起来比没有默认值时更整洁
动画:{
detailView.transform = CGAffineTransform.identity
detailView.center = CGPoint(x:finalFrame.midX,y:finalFrame.midY)
},
完成时间:{_
transitionContext.completeTransition(true)
}
)
}其他{
//更新结束动画
UIView.animate(withDuration:durationClosing,delay:0.0,options:.curveLinear,
动画:{
detailView.transform = scaleTransform
detailView.center = CGPoint(x:finalFrame.midX,y:finalFrame.midY)
},
完成时间:{_
如果!self.presenting {
self.dismissCompletion?()
}
transitionContext.completeTransition(true)
}
)
}
}
}
您可以根据需要随意修改和更改上述动画,但是出于我的目的,我使用了一些基本动画。 然后在您的ViewController中,设置CollectionViewDelegate和UIViewControllerTransitioningDelegate,如下所示:
扩展ViewController:UICollectionViewDelegate {
func collectionView(_ collectionView:UICollectionView,didSelectItemAt indexPath:IndexPath){
selectedCell = collectionView.cellForItem(at:indexPath)as! 宠物小精灵细胞
让pokemonDetailViewController = storyboard!.instantiateViewController(withIdentifier:“ DetailViewController”)为! DetailViewController
pokemonDetailViewController.pokemonName = myPokemon [indexPath.row] .pokemonName
pokemonDetailViewController.pokemonImageName = myPokemon [indexPath.row] .pokemonImage
pokemonDetailViewController.pokemonDetails = myPokemon [indexPath.row] .pokemonDetails
pokemonDetailViewController.transitioningDelegate =自我
present(pokemonDetailViewController,动画:true,完成:无)
}
}
扩展ViewController:UIViewControllerTransitioningDelegate {
func animationController(forPresented提出:UIViewController,提出:UIViewController,来源:UIViewController)-> UIViewControllerAnimatedTransitioning? {
后卫让originFrame = selectedCell.superview?.convert(selectedCell.frame,改为:nil)否则{
返回过渡
}
transition.originFrame = originFrame
transition.presenting = true
selectedCell.isHidden = true
返回过渡
}
func animationController(forDismissed被解雇:UIViewController)-> UIViewControllerAnimatedTransitioning? {
transition.presenting =假
返回过渡
}
}
结果应如下所示:
回购到该项目:
https://github.com/EricADockery/ViewTransitionMediumPost