动画是通过一系列静态图片(帧)快速显示来模拟动作和形状的变化过程。
在iOS中,创建基础动画很简单,只需要利用UIView
的类型方法:animate(withDuration:animations:)
。这个方法的原理就是,设置好开始状体和结束状态,然后* UIView animation* 创建中间的过程效果。继续上一篇开始用Swift开发iOS 10 - 13 Self Sizing Cells and Dynamic Type。
添加评级Button
下载图片包,添加到
xcassets
里。-
在detail view右上角添加一个Button,设置其内容为空,
image
为更添加的图片check
(一个对勾图标),type
为system
,tint
为white
。
为Button添加四个约束,右、上两个spacing约束,宽度和高度约束。
创建Restaurant Review视图控制器
- 在storyboard中新建一个View Controller。
- 在新建视图控制器中添加Image View,并改变其大小为整个view,先设置
image
属性为一个随机图片,比如cafeloisl
。 并设置一些约束。
按照下图设置之后是UI:
- 在Review的图片上添加一个
UIView
,x、y、宽度、高度分别是53、40、269、420。 - 添加Image View,宽度和高度分别为269,200,随机设置
image
- 添加一个内容为
You've dined here. What do you think?
的Label。字体风格为Light
,大小为27,居中退器,行数为2。 - 添加三个按钮内容分别为
Absolutely love it!
,Good
,I don't like it
。背景为红色,tint
为white
,字体是Light
和16。 - 设置三个按钮为一个stack view,改变
distribution
为Fill Equally
,spaing
为5。 - 为上面添加的
UIView
添加四个约束。上左右的spacing约束分别为20,37,37。高度约束为420。
- 为label添加左右下三个spacing约束,值都是15。
- 为stack view天机左右下三个spacing约束,分别为8,8,10。
创建Present modally类型的Segue
在开始用Swift开发iOS 10 - 10 Navigation Controller的介绍和Segue中介绍过Segue类型。Present modally是新页面将以动画形式从底部出现到覆盖整个手机屏幕。
- contrl-drag从对勾button到Review视图控制,选择Present modally。并设置新生成segue的
identifier
为showReview
。
定义如何退出Review View Controller
在Navigation Controller中自带了返回按钮,这边需要自己设置unwind segue。
- 在Review View Controller中的
UIView
的右上角添加一个关闭按钮,类似于对勾按钮,添加右上和宽度高度约束。
- 为了实现unwind segue,需要做两件事:
首先,在返回的的视图控制器(RestaurantDetailViewController
)中定义一个方法,定义这个方法是为了告诉xcode这个segue是可以返回的。
@IBAction func close(segue:UIStoryboardSegue) {
}
其次在IB中关联返回。control+drag关闭按钮到Exit,选择closeWithSegue:
。
为背景图片添加模糊效果
UIVisualEffectView
- 新建
ReviewViewController
继承至UIViewController
,关联上面新建视图控制器。 - 在
ReviewViewController
中添加背景图片结构,并关联图片。
@IBOutlet var backgroundImageView: UIImageView!
- 在
ReviewViewController
的viewDidLoad
中添加:
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
backgroundImageView.addSubview(blurEffectView)
模糊效果有点像在要添加的视图上面添加一个视图(UIVisualEffectView
),这图有模糊效果(UIBlurEffect
),模糊样式通过UIBlurEffectStyle
控制,有三种extraLight
, light
, dark
。
实现 UIView Animation
- 为准备实现动画效果的
UIView
添加接口,并关联。
@IBOutlet var containerView: UIView!
- 定义初始状态:在
ReviewViewController
的viewDidLoad
中添加:
containerView.transform = CGAffineTransform.init(scaleX: 0, y: 0)
- 定义介绍状态:在
ReviewViewController
的viewDidAppear
中添加:
override func viewDidAppear(_ animated: Bool) {
UIView.animate(withDuration: 0.3, animations: {
self.containerView.transform = CGAffineTransform.identity
})
}
CGAffineTransform.identity
表示原本设置的大小和位置状态。
Spring 动画
只要修改一下结束状态就可以了:
UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.2, options: .curveEaseInOut, animations: {
self.containerView.transform = CGAffineTransform.identity
}, completion: nil)
从上向下的动画
只要修改一下初始状态,把初始位置设置在上面即可:
containerView.transform = CGAffineTransform.init(translationX: 0, y: -1000)
组合两种变化
把containerView.transform = CGAffineTransform.init(translationX: 0, y: -1000)
修改成:
let scaleTransform = CGAffineTransform.init(scaleX: 0, y: 0)
let translateTransform = CGAffineTransform.init(translationX: 0, y: -1000)
let combineTransform = scaleTransform.concatenating(translateTransform)
containerView.transform = combineTransform
Unwind Segues 和数据传输
在Review View中点击三个不同评价按钮也通过Unwind Segues返回并传输数据。
- 在
RestaurantDetailViewController
在添加另外一个unwind action方法。
@IBAction func ratingButtonTapped(segue: UIStoryboardSegue) {
}
- 分别对三个按钮control+drag到Exit,选择
ratingButtonTappedWithSegue:
,并分别把三个unwind segue的identifier
改成great
good
dislike
。
- 在
Restaurant
中添加rating
属性:var rating = ""
- 更新
ratingButtonTapped(segue:)
:
@IBAction func ratingButtonTapped(segue: UIStoryboardSegue) {
if let rating = segue.identifier {
restaurant.isVisited = true
switch rating {
case "greate":
restaurant.rating = "Absolutely love it! Must try."
case "good":
restaurant.rating = "Pretty good."
case "dislike":
restaurant.rating = "I don't like it."
default:
break
}
}
tableView.reloadData()
}
- 更新
RestaurantDetailViewController
的tableView(_:cellForRowAt:)
中当fieldLabel
为“Been here”的valueLabel
的值:
cell.valueLabel.text = (restaurant.isVisited) ? "Yes, I've been herebefore. (restaurant.rating)" : "No"
修改ReviewViewController中的图片为相应的图片
在
ReviewViewController
中添加一个属性:
var restaurant: Restaurant!
在
RestaurantDetailViewController
中添加prepare(for:sender:)
方法,作为RestaurantDetailViewController
到ReviewViewController
的segue时调用,用于传输数据。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showReview" {
let destinationController = segue.destination as! ReviewViewController
destinationController.restaurant = self.restaurant
}
}
- 在
ReviewViewController
中添加图片接口。
@IBOutlet var topImageView: UIImageView!
- 在
ReviewViewController
的viewDidLoad
中显示图片:
let image = UIImage(named: self.restaurant.image)
backgroundImageView.image = image
topImageView.image = image
为closeButton添加动画效果
- 添加接口
@IBOutlet var closeButton: UIButton!
- 在
viewDieLoad
中添加:
closeButton.transform = CGAffineTransform.init(scaleX: 1000, y: 0) - 在
viewDidAppear:
添加:
UIView.animate(withDuration: 0.5, delay: 0.5, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.3, options: .curveEaseInOut, animations: {
self.closeButton.transform = CGAffineTransform.identity
}, completion: nil)
代码
Beginning-iOS-Programming-with-Swift
说明
此文是学习appcode网站出的一本书 《Beginning iOS 10 Programming with Swift》 的一篇记录
系列文章目录
- 开始用Swift开发iOS 10 - 1 前言
- 开始用Swift开发iOS 10 - 2 Hello World!第一个Swift APP
- 开始用Swift开发iOS 10 - 3 介绍Auto Layout
- 开始用Swift开发iOS 10 - 4 用Stack View设计UI
- [开始用Swift开发iOS 10 - 5 原型的介绍]
- 开始用Swift开发iOS 10 - 6 创建简单的Table Based App
- 开始用Swift开发iOS 10 - 7 定制Table Views
- 开始用Swift开发iOS 10 - 8 Table View和UIAlertController的交互
- 开始用Swift开发iOS 10 - 9 Table Row的删除, UITableViewRowAction和UIActivityViewController的使用
- 开始用Swift开发iOS 10 - 10 Navigation Controller的介绍和Segue
- 开始用Swift开发iOS 10 - 11 面向对象编程介绍
- 开始用Swift开发iOS 10 - 12 丰富Detail View和定制化Navigation Bar