捕获行为是定义了一个 item 运动到一个指定的点。
运动的过程像一个弹簧效果,在结束的时候会产生震荡。
//
// UISnapBehavior.h
// UIKit
//
// Copyright (c) 2012-2015 Apple Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIView.h>
#import <UIKit/UIDynamicBehavior.h>
NS_ASSUME_NONNULL_BEGIN
NS_CLASS_AVAILABLE_IOS(7_0) @interface UISnapBehavior : UIDynamicBehavior
// The point argument is expressed in the reference coordinate system
// 创建一个捕获行为
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point NS_DESIGNATED_INITIALIZER;
// 捕获的点
@property (nonatomic, assign) CGPoint snapPoint NS_AVAILABLE_IOS(9_0);
// 阻尼系数
@property (nonatomic, assign) CGFloat damping; // damping value from 0.0 to 1.0. 0.0 is the least oscillation. 默认值是 0.5
@end
NS_ASSUME_NONNULL_END
演示代码是 swift2.2 的
var testView: UIView?
var snapBehavior: UISnapBehavior?
var animator: UIDynamicAnimator?
override func viewDidLoad() {
super.viewDidLoad()
// item
let testView = UIView()
testView.backgroundColor = UIColor.redColor()
testView.frame = CGRect(x: 100, y: 100 , width: 10, height: 10)
self.view.addSubview(testView)
self.testView = testView;
// behavior
self.snapBehavior = UISnapBehavior(item: testView, snapToPoint: testView.center)
// animator
self.animator = UIDynamicAnimator(referenceView:self.view )
animator!.addBehavior(self.snapBehavior!)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// 获取当前触摸的位置
let touch = touches.first
// locationInView 是获取某个视图所在的坐标系中的点
let point = touch?.locationInView(self.view)
// 设置捕获的点
/*
重新设置这个捕获点的时候会产生一个动画效果
*/
self.snapBehavior?.snapPoint = point!
}
self.snapBehavior?.damping = 0.5 // 0.5 为默认值
damping : 值越大,震荡的幅度越小。
self.snapBehavior?.snapPoint = point! // 修改这个值 ,item 的 rect 和 rotation 都会发生变化。
当要设置的点 和 Behavior 中记录的点是一样的时候是不会产生震荡效果的。
遇到的一个坑:
var testView: UIView?
var snapBehavior: UISnapBehavior?
var animator: UIDynamicAnimator?
override func viewDidLoad() {
super.viewDidLoad()
// item
let testView = UIView()
testView.backgroundColor = UIColor.redColor()
testView.frame = CGRect(x: 100, y: 100 , width: 10, height: 10)
self.view.addSubview(testView)
self.testView = testView;
// 在这里没有创建行为
// animator
self.animator = UIDynamicAnimator(referenceView:self.view )
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// 获取当前触摸的位置
let touch = touches.first
let point = touch?.locationInView(view)
print(self.snapBehavior?.snapPoint)
// 注释了这里就会有一个 bug ,多次点击屏幕后就没有动画效果了。item 不动了。 但是 item 的 snapPoint 还是变化的。所有还是建议我第一个示例的写法。
// if self.snapBehavior != nil {
// self.animator?.removeBehavior(self.snapBehavior!)
// }
self.snapBehavior = UISnapBehavior(item: self.testView!, snapToPoint: point!)
self.animator?.addBehavior(self.snapBehavior!)
}