入门
打开启动项目并选择Main.storyboard开始浏览:
01.png第一个视图的视图列表,HomeViewController
包含应用点击列表中的图像列表。每次显示用户的图像时HomeViewController
,DetailsViewController
标题和描述该视图。
HomeViewController.swift和DetailsViewController.swift中已经有很快的代码来支持基本应用程序。并运行应用程序以查看应用程序的外观和感觉:
02.png点击其中的食谱图片,详细信息屏幕会通过标准的纵向封面过渡出现。这可能没有价值,但你的食谱更好
您的工作是您的应用程序添加一些自定义的点击您的演示动画,现在为显示!
03.gif卷起袖子,穿上开发者的围裙,为你定制展示机器人的内部工作做好准备!
自定义转场的幕后花絮
UIKit 允许您通过委托给您的用户自定义视图。您可以通过委托给您的主视图或创建您的目标的另一类UIViewControllerTransitioningDelegate
。
当你呈现一个界面的视图时,UIKit 是否应该使用自定义转换。以下是自定义过渡的新任务:委托
04.png如果UIKit 调用animationController(forPresented:presenting:source:)
来查看它是否是一个UIViewControllerAnimatedTransitioning
对象nil
,则 UIKit 使用返回的转换方法。如果 UIKit 接收到UIViewControllerAnimatedTransitioning
对象,则 UIKit 使用该对象作为过渡的动画。
UIKit 可以在之前使用自定义动画,还有几个步骤:
05.pngUIKit首先查询你的动画作品——简称为动画师——以秒为单位的自定义过渡时间,调用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面试要点
网友评论