【发布时间】:2018-04-06 23:39:47
【问题描述】:
我研究了很多,但我能在任何地方找到的唯一示例是为了定义 UIView 的边界,以便它们在对象的外部相互碰撞/反弹。
示例:一个球撞到另一个球,它们相互弹开。
但我想做的是创建一个圆形视图来包含其他 UIView,这样包含边界是一个圆形,而不是默认的正方形。有没有办法做到这一点?
【问题讨论】:
标签: swift animation collision-detection uikit-dynamics
我研究了很多,但我能在任何地方找到的唯一示例是为了定义 UIView 的边界,以便它们在对象的外部相互碰撞/反弹。
示例:一个球撞到另一个球,它们相互弹开。
但我想做的是创建一个圆形视图来包含其他 UIView,这样包含边界是一个圆形,而不是默认的正方形。有没有办法做到这一点?
【问题讨论】:
标签: swift animation collision-detection uikit-dynamics
是的,这完全可能。实现圆内碰撞的关键是
UIBezierPath)和referenceView 设置为圆形视图。输出:
故事板设置:
下面是上述 Storyboard 的视图控制器的代码。魔法发生在simulateGravityAndCollision 方法中:
class ViewController: UIViewController {
@IBOutlet weak var redCircle: UIView!
@IBOutlet weak var whiteSquare: UIView!
var animator:UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
self.redCircle.setCornerRadius(self.redCircle.bounds.width / 2)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { [unowned self] in
self.simulateGravityAndCollision()
}
}
//IMPORTANT
func simulateGravityAndCollision() {
//The dynamic animation happens only within the reference view, i.e., our red circle view
animator = UIDynamicAnimator.init(referenceView: self.redCircle)
//Only the inside white square will be affected by gravity
let gravityBehaviour = UIGravityBehavior.init(items: [self.whiteSquare])
//We also apply collision only to the white square
let collisionBehaviour = UICollisionBehavior.init(items:[self.whiteSquare])
//This is where we create the circle boundary from the redCircle view's bounds
collisionBehaviour.addBoundary(withIdentifier: "CircleBoundary" as NSCopying, for: UIBezierPath.init(ovalIn: self.redCircle.bounds))
animator.addBehavior(gravityBehaviour)
animator.addBehavior(collisionBehaviour)
}
}
extension UIView {
open override func awakeFromNib() {
super.awakeFromNib()
self.layer.allowsEdgeAntialiasing = true
}
func setCornerRadius(_ amount:CGFloat) {
self.layer.cornerRadius = amount
self.layer.masksToBounds = true
self.clipsToBounds = true
}
}
【讨论】: