如果您使用UIDynamicAnimator,您可以为将发生碰撞的项目定义collisionBoundsType 和collisionBoundingPath,例如:
@IBDesignable public class BallView : UIView {
@IBInspectable public var fillColor: UIColor = UIColor.blackColor() {
didSet { setNeedsLayout() }
}
override public var collisionBoundsType: UIDynamicItemCollisionBoundsType {
return .Path
}
override public var collisionBoundingPath: UIBezierPath {
let radius = min(bounds.size.width, bounds.size.height) / 2.0
return UIBezierPath(arcCenter: CGPointZero, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)
}
private var shapeLayer: CAShapeLayer!
public override func layoutSubviews() {
if shapeLayer == nil {
shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.clearColor().CGColor
layer.addSublayer(shapeLayer)
}
let radius = min(bounds.size.width, bounds.size.height) / 2.0
shapeLayer.fillColor = fillColor.CGColor
shapeLayer.path = UIBezierPath(arcCenter: CGPoint(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0), radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2.0), clockwise: true).CGPath
}
}
@IBDesignable public class PaddleView : UIView {
@IBInspectable public var cornerRadius: CGFloat = 5 {
didSet { setNeedsLayout() }
}
@IBInspectable public var fillColor: UIColor = UIColor.blackColor() {
didSet { setNeedsLayout() }
}
override public var collisionBoundsType: UIDynamicItemCollisionBoundsType {
return .Path
}
override public var collisionBoundingPath: UIBezierPath {
return UIBezierPath(roundedRect: CGRect(x: -bounds.size.width / 2.0, y: -bounds.size.height / 2.0, width: bounds.width, height: bounds.height), cornerRadius: cornerRadius)
}
private var shapeLayer: CAShapeLayer!
public override func layoutSubviews() {
if shapeLayer == nil {
shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.clearColor().CGColor
layer.addSublayer(shapeLayer)
}
shapeLayer.fillColor = fillColor.CGColor
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height), cornerRadius: cornerRadius).CGPath
}
}
如果您这样做,然后将这些项目添加到您的UICollisionBehavior,它将尊重您为项目定义的冲突边界。例如:
上图说明了一个扫视,就像您的原始图像一样。如果你想让它即使碰到桨的边缘也能弹起来,你可以为UICollisionBehavior指定collisionDelegate并给它一个新的方向:
let collision = UICollisionBehavior(items: [paddleView, ballView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
self.animator.addBehavior(collision)
并符合UICollisionBehaviorDelegate再执行collisionBehavior(beganContactForItem:withItem:atPoint:):
func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item1: UIDynamicItem, withItem item2: UIDynamicItem, atPoint p: CGPoint) {
let postCollisionDirection = UIDynamicItemBehavior(items: [ballView])
postCollisionDirection.addLinearVelocity(CGPoint(x: ballView.center.x - paddleView.center.x, y: -200), forItem: ballView)
animator.addBehavior(postCollisionDirection)
}
这会产生如下内容:
显然,您必须花很多时间才能获得所需的效果,但它说明了检测碰撞并相应地为球添加线速度的基本思想。