手势
//1. 视图默认可以接收触摸事件
let firstView = FirstView(frame: CGRect(x: 100, y: 100, width: 300, height: 300))
//当父视图不能交互时,所有子视图都不能交互
//UIImageView: 默认为false,不能交互
// firstView.userInteractionEnabled = false
firstView.backgroundColor = UIColor.redColor()
self.view.addSubview(firstView)
//2. 视图结构不能改变事件传递顺序
let secondView = SecondView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
//用户是否可以交互
//UIView默认为true
// secondView.userInteractionEnabled = false
secondView.backgroundColor = UIColor.greenColor()
// self.view.addSubview(secondView)
firstView.addSubview(secondView)
let rotate = UIRotationGestureRecognizer(target: self, action: #selector(didRotate(_:)))
firstView.addGestureRecognizer(rotate)
let pinch = UIPinchGestureRecognizer(target: self, action: #selector(didPinch(_:)))
firstView.addGestureRecognizer(pinch)
1.使用手势实现旋转
2.使用手势实现缩放
func didRotate(sender: UIRotationGestureRecognizer) {
let firstView = sender.view!
// firstView?.transform = CGAffineTransformMakeRotation(sender.rotation)
firstView.transform = CGAffineTransformRotate(firstView.transform, sender.rotation - rotation)
rotation = sender.rotation
print(sender.rotation)
if sender.state == .Ended {
rotation = 0
}
//手势每次都是从0开始
print("rotate: ", sender.rotation)
}
func didPinch(sender: UIPinchGestureRecognizer) {
let firstView = sender.view!
//??????
firstView.transform = CGAffineTransformScale(firstView.transform, sender.scale - scale + 1 , sender.scale - scale + 1)
//缩放的比例取两次的差值加1
scale = sender.scale
if sender.state == .Ended {
scale = 1
}
print("scale: ", sender.scale)
}
设置动画
1.UIView层
会影响属性值
1.1类方法: UIView.animateWithDuration
有三种类方法,参数越来越多.
1.2
(1) UIView.beginAnimations()开始设置动画
(2) UIView.set....设置动画属性
可以通过UIView.setAnimationDelegate 设置代理,设置将要开始动画或者结束动画执行的方法(函数)
(3)UIView.commitAnimations()提交动画,开始执行
//1. 开始设置动画
UIView.beginAnimations("first", context: nil)
//2. 设置动画属性
UIView.setAnimationDuration(10)
UIView.setAnimationRepeatCount(2)
UIView.setAnimationDelegate(self) //设置代理方法所在的对象
UIView.setAnimationWillStartSelector(#selector(animateWillStart(_:context:)))
UIView.setAnimationDidStopSelector(#selector(animateDidStop(_:finished:context:)))
//3. 设置目标属性
self.redView.backgroundColor = UIColor.greenColor()
//4. 提交动画,开始执行
UIView.commitAnimations()
//animationWillStart:(NSString *)animationID context:(void *)context
func animateWillStart(animationID: NSString, context: UnsafePointer<Void>) {
print("will start")
}
//NSNumber
func animateDidStop(animationID: NSString, finished: Bool, context: UnsafePointer<Void>) {
print(finished)
}
2.layer层
2.1 CATransaction
会影响属性值
与上个类似
(1) CATransaction.begin()
(2) 设置动画时长等设置属性
(3) 改变layer的属性,默认会有动画(文档里属性注释里面有animated的)
(4) CATransaction.commit()
CATransaction.begin()
CATransaction.setAnimationDuration(5)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn))
//1. CALayer属性改变时,默认会有动画
redLayer.frame = CGRect(x: 200, y: 200, width: 50, height: 50)
redLayer.cornerRadius = 25
redLayer.borderWidth = 10
CATransaction.commit()
2.2 CAPropertyAnimation 的两个子类
不影响实际属性值
2.2.1 CABasicAnimation
使用时要创建对象
let ani01 = CABasicAnimation(keyPath: "backgroundColor")
ani01.duration = 5
// ani01.fromValue = NSValue(CGPoint: CGPoint(x: 200, y: 0))
// ani01.toValue = NSValue(CGPoint: CGPoint(x: 200, y: 200))
// ani01.byValue = NSValue(CGPoint: CGPoint(x: 200, y: 100))
ani01.toValue = UIColor.purpleColor().CGColor
redLayer.addAnimation(ani01, forKey: "ani01")
- fromValue 起点
- byVlaue 起点到终点的相对偏移量
- toValue 终点
- 同时可以有两个条件起作用
- 如果只有一个条件,那么任何一个条件的点都成为终点
- 如果是只有by和to,那么会自动根据终点和起点算出应该出发的点...
2.2.2 CAKeyframeAnimation
let ani02 = CAKeyframeAnimation(keyPath: "position")
//关键帧的位置(关键点)
ani02.values = [
NSValue(CGPoint: CGPoint(x: 0, y: 0)),
NSValue(CGPoint: CGPoint(x: 200, y: 0)),
NSValue(CGPoint: CGPoint(x: 200, y: 200)),
NSValue(CGPoint: CGPoint(x: 0, y: 200))
]
//到达关键帧(关键点的时刻,0-1)
ani02.keyTimes = [0, 0.8, 0.9, 1]
redLayer.addAnimation(ani02, forKey: "ani02")
这个类可以设置多个关键点(关键帧),可以设置不同的时间点执行
这个类有个属性 path -> CGPath类型
所以可以创建一个CGPath类型的轨迹,然后执行动画
//创建可变的一个CGPath对象
//也可以直接用CGPathCreatWithEllipseInRect创建一个圆的轨迹
let path = CGPathCreateMutable()
//添加一个椭圆的轨迹
CGPathAddEllipseInRect(path, nil, CGRect(x: 0, y: 0, width: 200, height: 200))
ani02.path = path
ani02.duration = 10
redLayer.addAnimation(ani02, forKey: "ani02")
2.2.3 CAAnimationGroup
//CAAnimationGroup.animations
可以添加多个CAAnimation
类的对象
使用Layer画图
//可以绘制图形
let shapeLayer = CAShapeLayer()
shapeLayer.frame = self.view.bounds
shapeLayer.strokeColor = UIColor.blackColor().CGColor
shapeLayer.fillColor = UIColor.clearColor().CGColor
//创建一个可变的CGPath
let path = CGPathCreateMutable()
//添加一个椭圆的轨迹
CGPathAddEllipseInRect(path, nil, CGRect(x: 0, y: 0, width: 200, height: 200))
shapeLayer.path = path
self.view.layer.addSublayer(shapeLayer)
//可以显示文字
let textLayer = CATextLayer()
textLayer.string = "这里是CATextLayer"
textLayer.foregroundColor = UIColor.redColor().CGColor
textLayer.frame = CGRect(x: 0, y: 200, width: 200, height: 50)
self.view.layer.addSublayer(textLayer)
let imageLayer = CALayer()
imageLayer.frame = CGRect(x: 200, y: 200, width: 100, height: 200)
imageLayer.contents = UIImage(named: "showqrcode.jpeg")?.CGImage
self.view.layer.addSublayer(imageLayer)
contets-> contents: AnyObject?
支持CGImage对象
layer和UIView用法差不多,layer更底层一些