×

# 如何用 UIKit Dynamics 进行碰撞检测

### 设置工程

Product Name 使用 IOS10CollisionDectectionTutorial（译者注：这里的 Dectection 估计是错别字，应该是 Detection），填写自己的 Organization Name 和 Organization Identifier，Language 一栏选择 Swift，Devices 一栏选择 iPhone。

``````func drawLineFromPoint(fromX: CGFloat, toPoint toX: CGFloat, pointY y: CGFloat) {
let currentContext = UIGraphicsGetCurrentContext()

if let currentContext = currentContext {
currentContext.setLineWidth(5.0)
currentContext.move(to: CGPoint(x: fromX, y: y))
currentContext.strokePath();
}}
``````

``````override func draw(_ rect: CGRect) {

drawLineFromPoint(fromX: 0, toPoint: bounds.size.width/3, pointY: bounds.size.height - 100.0)
drawLineFromPoint(fromX: bounds.size.width/3, toPoint:bounds.size.width*0.67, pointY:bounds.size.height - 150.0)
drawLineFromPoint(fromX: bounds.size.width*0.67, toPoint:bounds.size.width, pointY:bounds.size.height - 100.0)}
``````

ViewController.swift 文件中，需要声明一些变量，来跟踪记录 view，如下所示：

``````var squareViews:[UIView] = []
var animator:UIDynamicAnimator!
var colors:[UIColor] = []
var centerPoint:[CGPoint] = []
var sizeOfSquare:CGSize!
``````

squareViews 将包含所需的 view，view 需要颜色数组、centerPin 数组和 sizeOfSquare（方块的大小）这些属性。animator 属性要用于动画动作。接下来继续添加下列属性：

``````var leftBoundaryHeight:CGFloat!
var middleBoundaryHeight:CGFloat!
var rightBoundaryHeight:CGFloat!
var leftBoundaryWidth:CGFloat!
var middleBoundaryWidth:CGFloat!
var leftSquareCenterPointX:CGFloat!
var middleSquareCenterPointX:CGFloat!
var rightSquareCenterPointX:CGFloat!
var squareCenterPointY:CGFloat!
``````

``````func setBoundaryValues() {
leftBoundaryHeight = view.bounds.size.height - 100.0
middleBoundaryHeight = view.bounds.size.height - 150.0
rightBoundaryHeight = view.bounds.size.height - 100.0
leftBoundaryWidth = view.bounds.size.width/3
middleBoundaryWidth = view.bounds.size.width * 0.67
leftSquareCenterPointX = view.bounds.size.width/6
middleSquareCenterPointX = view.bounds.size.width/2
rightSquareCenterPointX = view.bounds.size.width * 0.84
squareCenterPointY = view.bounds.size.height - 400
}
``````

``````override func viewDidLoad() {

setBoundaryValues()

// 创建颜色数组
colors = [UIColor.red, UIColor.blue, UIColor.green, UIColor.purple, UIColor.gray]

// 创建方块的中心点（centerpoint）
let leftCenterPoint = CGPoint(x: leftSquareCenterPointX, y: squareCenterPointY)
let middleCenterPoint = CGPoint(x: middleSquareCenterPointX, y: squareCenterPointY)
let rightCenterPoint = CGPoint(x:rightSquareCenterPointX, y: squareCenterPointY)
centerPoint = [leftCenterPoint,middleCenterPoint,rightCenterPoint]

// 设置方块的大小
sizeOfSquare = CGSize(width: 50.0, height: 50.0)
}
``````

``````@IBAction func releaseSquare(_ sender: Any) {
let newView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: sizeOfSquare.width, height: sizeOfSquare.height))

let randomColorIndex = Int(arc4random()%5)
newView.backgroundColor = colors[randomColorIndex]

let randomCenterPoint = Int(arc4random()%3)
newView.center = centerPoint[randomCenterPoint]

squareViews.append(newView)
}
``````

``````animator = UIDynamicAnimator(referenceView: view)

// 创建重力
let gravity = UIGravityBehavior(items: squareViews)

// 创建碰撞检测
let collision = UICollisionBehavior(items: squareViews)

// 设置碰撞的边界
collision.addBoundary(withIdentifier: "leftBoundary" as NSCopying, from: CGPoint(x: 0.0,y: leftBoundaryHeight), to: CGPoint(x: leftBoundaryWidth, y: leftBoundaryHeight))
collision.addBoundary(withIdentifier: "middleBoundary" as NSCopying, from: CGPoint(x: view.bounds.size.width/3,y: middleBoundaryHeight), to: CGPoint(x: middleBoundaryWidth, y: middleBoundaryHeight))
collision.addBoundary(withIdentifier: "rightBoundary" as NSCopying, from: CGPoint(x: middleBoundaryWidth,y: rightBoundaryHeight), to: CGPoint(x: view.bounds.size.width, y: rightBoundaryHeight))

collision.collisionMode = .everything