美文网首页
iOS 动画教程:自定义视图控制器演示转换

iOS 动画教程:自定义视图控制器演示转换

作者: iOS丶lant | 来源:发表于2022-05-06 15:14 被阅读0次

入门

打开启动项目并选择Main.storyboard开始浏览:

01.png

第一个视图的视图列表,HomeViewController包含应用点击列表中的图像列表。每次显示用户的图像时HomeViewControllerDetailsViewController标题和描述该视图。

HomeViewController.swiftDetailsViewController.swift中已经有很快的代码来支持基本应用程序。并运行应用程序以查看应用程序的外观和感觉:

02.png

点击其中的食谱图片,详细信息屏幕会通过标准的纵向封面过渡出现。这可能没有价值,但你的食谱更好

您的工作是您的应用程序添加一些自定义的点击您的演示动画,现在为显示!

03.gif

卷起袖子,穿上开发者的围裙,为你定制展示机器人的内部工作做好准备!

自定义转场的幕后花絮

UIKit 允许您通过委托给您的用户自定义视图。您可以通过委托给您的主视图或创建您的目标的另一类UIViewControllerTransitioningDelegate

当你呈现一个界面的视图时,UIKit 是否应该使用自定义转换。以下是自定义过渡的新任务:委托

04.png

如果UIKit 调用animationController(forPresented:presenting:source:)来查看它是否是一个UIViewControllerAnimatedTransitioning对象nil,则 UIKit 使用返回的转换方法。如果 UIKit 接收到UIViewControllerAnimatedTransitioning对象,则 UIKit 使用该对象作为过渡的动画。

UIKit 可以在之前使用自定义动画,还有几个步骤:

05.png

UIKit首先查询你的动画作品——简称为动画师——以秒为单位的自定义过渡时间,调用animateTransition(using:)它。这是你接下来的动画成为焦点的时候。

animateTransition(using:)中,您可以随心所欲地访问显示屏的视图以及新视图上的新视图。

现在您已经了解了一些关于自定义可以启动控制器的原理,您创建自己的工作。

实施超越

委托的任务是管理实际动画的动画器对象,因此首先必须为动画器类创建一个存根,然后由您编写委托执行代码。

从 Xcode 的主菜单中,选择File ▸ New ▸ File...并选择模板iOS ▸ Source ▸ Cocoa Touch Class

将新类命名为选择PopAnimator,确保 Swift,并成为NSObject的子类。

打开 PopAnimator.swift并更新类定义以创建符合UIViewControllerAnimatedTransitioning协议,如下所示:

类PopAnimator : NSObject , UIViewControllerAnimatedTransitioning {

}

你会看到一些来自你的委托,因为你实现没有需要的委托方法。

将以下方法添加到类中:

func  transitionDuration(使用transitionContext:UIViewControllerContextTransitioning?)
    -> 时间间隔{
  返回0
}

上面的0值只是一个占位符值。稍后您将在完成项目时将替换为实际值。

现在,将以下方法存根添加到类中:

func  animateTransition(使用transitionContext:UIViewControllerContextTransitioning) {

}

上面的存根将保存您的动画,添加它应该清除 Xcode 中已经存在的剩余代码。

现在您已经有基本的动画师类,您可以继续在视图端实现委托方法。

连接代表

打开HomeViewController.swift将以下扩展名添加到文件中:

// MARK: - UIViewControllerTransitioningDelegate

扩展HomeViewController:UIViewControllerTransitioningDelegate {

}

此代码样式转换符合委托协议,稍后您将在此处该协议添加。

prepare(for:sender:)在HomeViewController.swift中找到您将看到的设置信息视图的详细方法,在该代码。detailsViewController``HomeViewController

在设置配方之前添加以下行:

detailsViewController.transitioningDelegate =  self

HomeViewController现在,每当您在屏幕上显示详细信息视图时,UIKit 会请求一个动画对象。但是,您还没有实现任何UIViewControllerTransitioningDelegate方法,UIKit 仍将使用默认转换。

下一步是实际创建您的动画对象,并在请求时将其返回给 UIKit。

使用动画师

在顶部添加以下新属性HomeViewController

让过渡=  PopAnimator ()

PopAnimator您只需要一个实例,因为在操作界面时您可以继续使用相同的对象,因为每次转换相同的对象。PopAnimator

现在,将第一个委托方法添加到 UIViewControllerTransitioningDelegate 扩展中HomeViewController

函数动画机器人(
  forPresented UI:UIViewController, 
  UI呈现:UIViewController,来源ViewController) 
    -> UIViewControllerAnimatedTransitioning? {
  返回过渡
}

采用一些参数决定是否自定义动画的这个决定。在指导方法中,您将始终返回您的实例,PopAnimator因为您只需要将演示文稿归还本。

您已经使用了如何处理经理的方法呢?

添加以下委托方法来处理此问题:

func  animationController ( forDismisseddismissed : UIViewController )
    -> UIViewControllerAnimatedTransitioning? {
  返回零
}

您的其他能力与您之前的一个方法相同:您检查哪个视图被关闭并决定返回nil使用默认动画还是自定义方法暂停动画并使用它。目前,您返回nil,等到稍后实现动画。

您最近有一个自定义动画师来处理您的自定义过渡。但它有有效吗?

制作并运行您的应用程序并点击其中一个配方图像:

06.png

为什么?有一个自定义动画师来解决您驱动转换的问题,但是……哦,等等,您还没有向动画师类添加任何代码!将在下一节中显示。

创建你的过渡动画师

PopAnimator.swift 。您将在此处添加代码以在两个视图中打开之间进行转换。

首先,将以下属性添加到此类:

让持续
时间=  0.8 
var =真
var originFrame =  CGRect .zero

您将duration在多个地方使用,例如当告诉您 UIKit 转换需要很长时间以及何时创建动画时。

您还定义presenting告诉动画师是一位高级操作师。您的情况进行监视,因为通常情况下,向前运行动画以类,相反希望您将运行以查看此情况。

您将使用originFrame存储的图像的原始帧——将需要它来从原始帧最终到全屏图像,反之用户。originFrame当获取您当前给定的图像时,将其帧传送动画师实例时,请留意稍后。

您现在可以继续使用这些UIViewControllerAnimatedTransitioning方法。

将里面的代码替换为transitionDuration(using:)以下内容:

返回时长

使用该duration属性可以让轻松地转换动画。您可以简单地使用该属性的值,使您可以轻松地运行该属性的值。

设置转换的时间

是时候给了animateTransition(using:)。这个方法有一个参数,为UIViewControllerContextTransitioning,可以转换的参数和让您访问图形。

在开始处理代码之前,了解动画时间实际上什么很重要。

当两个视图容器之间的视图被转换开始时,现有的视图被转换到中,并且新到视图时的视图被创建但不添加,如下图所示:

07.png

因此,如果您的视图需要新视图添加到内的过渡容器中animateTransition(using:),“动画化”外观并“动画化”)需要。

情况下,过渡动画完成后,旧视图从过渡容器中移除。

08.png

在这个厨房里有很多之前需要创建一个简单的过渡动画,然后看看它是如何工作的,然后再实现一个更酷但更复杂的过渡。

添加 展开 过渡

您将把下面这些简单的代码展开过渡,开始以了解自定义animateTransition(using:)过渡。

让 containerView = transitionContext.containerView
让 toView = transitionContext.view(forKey: .to)!

首先,您获取containerView动画将发生的位置,然后获取新视图并将其存储在toView

过渡方法可以让对象有两个非常方便的让您访问过渡播放器:

  • 视图(forKey:)UITransitionContextViewKey.from:这使您可以通过参数或UITransitionContextViewKey.to分别 访问“旧”和“新”图形的视图。
  • viewController(forKey:)UITransitionContextViewControllerKey.from:这使您可以通过参数或UITransitionContextViewControllerKey.to分别 访问“旧”和“新”视图。

此时,您拥有容器的视图和要呈现的视图。接下来,需要将您作为子视图的视图处理到中,并添加到容器中以某种方式进行动画处理。

将以下内容添加到animateTransition(using:)

containerView.addSubview(toView)
toView.transform =  CGAffineTransform (scaleX: 0.0 , y: 0.0 )
 UIView .动画(
  withDuration:持续时间,
  动画:{
    toView.transform =  CGAffineTransform (scaleX: 1.0 , y: 1.0 )
  },
  完成:{ _  in 
    transitionContext.completeTransition( true )
  }
)

请注意,您completeTransition(_:)在动画完成块中调用了转换时间。这将告诉 UIKit 你的过渡动画已经完成并且 UIKit 可以自由地封装视图场景的过渡。

并运行您的应用程序并单击列表中的一个,在您的主视图上查看配方概览

09.png

过渡是可以接受的,而且你已经看到了要做什么animateTransition(using:)——但是你会添加一些更好的东西!

添加过渡过渡

替换为下面的内容的代码结构不同,因此animateTransition(using:)

让 containerView = transitionContext.containerView
让 toView = transitionContext.view(forKey: .to)!
让 recipeView =?toView : transitionContext.view(forKey: .from)!

containerView``toView如果换成“您的屏幕上的新视图”。如果只是,否则从时间中它获取,因为它来自于现在的展示位置,recipeView无论是展示位置还是展示视图,都将呈现给您。当您呈现详细信息画面时,建筑面积缩小到整个画面。toView``recipeView

将以下内容添加到animateTransition(using:)

让 initialFrame =视角?originFrame : recipeView.frame
让 finalFrame =框架?recipeView.frame: originFrame

让 xScaleFactor =透视?
  initialFrame.width / finalFrame.width :
  finalFrame.width / initialFrame.width

让 yScaleFactor =呈现?
  initialFrame.height / finalFrame.height :
  finalFrame.height / initialFrame.height

在上面的代码中,您最初检测和最终的动画帧,然后计算在每个视图之间进行处理时在每个轴上应用的所需因子。

现在,您需要仔细查看新的视图,显示车间在的显示。现在点击点击的图像看起来像以填充屏幕显示。

缩放视图

将以下内容添加到animateTransition(using:)

让 scaleTransform =  CGAffineTransform (scaleX: xScaleFactor, y: yScaleFactor)

如果呈现{
  recipeView.transform = scaleTransform
  recipeView.center =  CGPoint (
    x: 初始帧.midX,
    y: 初始帧.midY)
  recipeView.clipsToBounds =  true
}

recipeView.layer.cornerRadius =层次?20.0 : 0.0 
recipeView.layer.masksToBounds =  true

外观新视图时,您可以设置它的比例和位置,设置与最终帧的大小和位置完全匹配。还可以设置正确的拐角半径。

现在,将最后的代码添加到animateTransition(using:)

containerView.addSubview(toView)
containerView.bringSubviewToFront(recipeView)

UIView .动画(
  withDuration:持续时间,
  延迟:0.0,
  使用SpringWithDamping :0 . 5,
  初始弹簧速度:0 . 2,
  动画:{
    recipeView.transform =  self .presenting ?.identity : scaleTransform
    recipeView.center =  CGPoint (x: finalFrame.midX, y: finalFrame.midY)
    recipeView.layer.cornerRadius =  ! self .presenting ?20.0 : 0.0 
  },完成:{ _  in 
    transitionContext.completeTransition( true )
})

这将添加toView到容器中。制作后,您需要确保recipeView它位于顶部,因为这是您动画的视图。请记住,在关闭时,toView是原始视图,因此,在第一行中,您会将您添加到其他所有内容之前,并将其添加到您之前的动画将被隐藏recipeView

然后,您可以启动动画。

animations表达式内部,更改时,位置recipeView和角度。以匹配原始图像大小。

此时,您已经通过将新的视图来设置舞台上的设置,您已经在初始图像和最终帧之间进行了动画处理,最后,您已经调用了将内容还给completeTransition(using:)UIKit。查看您的代码了!

为您制作并运行您的应用程序图像。单击一个配方,以查看第一个图形转换程序。

10.png

嗯,它并不完美,但你处理了一些粗糙的边缘,但是你的动画,你想要的!

添加一些波兰语

目前,您的动画从左上角开始,这是因为默认originFrame的原点(0, 0)所在,而您将永远开始其价值。

打开HomeViewController.swiftanimationController(forPresented:presenting:source:)并在代码返回过渡之前将以下代码添加到顶部:

警卫
  让 selectedIndexPathCell = tableView.indexPathForSelectedRow,
  让 selectedCell = tableView.cellForRow(at: selectedIndexPathCell)
    作为?食谱表视图单元格,
  让 selectedCellSuperview = selectedCell.superview
  别说{
    返回零
}

transition.originFrame = selectedCellSuperview.convert(selectedCell.frame, to: nil )
过渡.originFrame =  CGRect (
  x:transition.originFrame.origin.x +  20,
  y:transition.originFrame.origin.y +  20,
  宽度:transition.originFrame.size.width -  40,
  高度:transition.originFrame.size.height -  40
)

过渡.透视=真
selectedCell.shadowView.isHidden =  true

这将设置您指定的单元格,将获取originFrame转换设置为的框架selectedCellSuperview,点击的单元格。

再次构建并运行您该应用程序,然后点击列表中的不同配方以查看过渡效果如何。

11.png

添加关闭过渡

剩下的代码做的就是解散细节画面。实际上,您在动画中完成了工作画面 - 过渡动画执行逻辑耍弄设置,以您的最终帧和最终帧都可以向前移动和回放动画。甜的!

打开HomeViewController正文.swift并用以下内容替换animationController(forDismissed:)

跨越。=假
返回过渡

告诉您的动画师对象您正在关闭视图,以便动画代码以正确的方向运行。

构建并运行应用程序以查看结果。点击食谱,然后点击屏幕左上角的X按钮将其关闭。

12.gif

过渡动画看起来很像您,但请注意选择已经从表格视图中删除了!当您关闭详细信息屏幕时,需要确保点击的图像重新出现。

PopAnimator.swift闭包打开类添加一个新的属性:

var dismissCompletion: (() -> Void ) ?

这将允许您在某些代码完成时以在关闭运行。

,在对的调用中找到下面的指令animateTransition(using:)并将其交付到完成处理程序中animate(...),就在对调用之前completeTransition()

如果!自我.presenting {
  自我.dismissCompletion ?() 
}

代码dismissCompletion在动画完成后执行,这是显示原始图像的最佳位置。

打开代码HomeViewController.swift下面的添加到文件的主类中:


覆盖func  viewDidLoad () {
   super .viewDidLoad() 

  transition.dismissCompletion = { [弱自我] in
    警卫
      让 selectedIndexPathCell =  self ? .tableView.indexPathForSelectedRow,
      让 selectedCell =  self ?.tableView.cellForRow 
      ( at 
  : 
    selectedIndexPathCell )
作为
        ?
        _ 
    _
 

此代码显示选择格的原始图像,以在过渡动画完成后替换配方详细信息视图。

制作您的应用程序以获取并运行的过渡动画,因为食谱的方式不会在此中遗弃!

13.gif

设备方向转换

您可以将设备方向更改从自己的图形到自己不同的转换方式,只是不同的型号。

该应用程序是使用自动制造的,因此您需要单独进行更改。仅使用旋转设备并过渡效果(如果在 iPhone 命令-中进行测试,请左箭头)!

14.gif

结论

本教程的最终项目资料下载地址
链接:https://pan.baidu.com/s/1WLV1O0clH2dgyeCyz2bidQ
提取码:1ck4

这里也推荐一些面试相关的内容,祝各位网友都能拿到满意offer!
GCD面试要点
block面试要点
Runtime面试要点
RunLoop面试要点
内存管理面试要点
MVC、MVVM面试要点
网络性能优化面试要点
网络编程面试要点
KVC&KVO面试要点
数据存储面试要点
混编技术面试要点
设计模式面试要点
UI面试要点

相关文章

网友评论

      本文标题:iOS 动画教程:自定义视图控制器演示转换

      本文链接:https://www.haomeiwen.com/subject/yntzyrtx.html