未调用 UICollisionBehaviorDelegate 方法
UICollisionBehaviorDelegate methods not called
我开发了一个应用程序并使用 UIKitDynamics 实现了碰撞检测。
碰撞检测正在运行。但不知何故 UICollisionBehaviorDelegate 方法没有被调用。
未显示任何警告或错误。
我创建了一个示例项目来演示该问题:
import UIKit
class ViewController: UIViewController {
private var dynamicAnimator: UIDynamicAnimator?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.initPhysics()
}
fileprivate var initalized = false
fileprivate func initPhysics() {
if initalized {
return
}
initalized = true
let physicsView = UIView(frame: view.bounds.insetBy(dx: 40, dy: 40))
physicsView.backgroundColor = UIColor.black
self.dynamicAnimator = UIDynamicAnimator(referenceView: physicsView)
physicsView.isUserInteractionEnabled = false
view.addSubview(physicsView)
//Create ball
let frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let rect = UIView(frame: frame)
rect.backgroundColor = UIColor.red
physicsView.addSubview(rect)
let behavior = UIDynamicItemBehavior(items: [rect])
behavior.elasticity = 1.0
behavior.resistance = 0.0
behavior.friction = 0.0
behavior.allowsRotation = false
self.dynamicAnimator?.addBehavior(behavior)
//collision behavior setup
let collisionBehavior = UICollisionBehavior(items: [rect])
collisionBehavior.collisionDelegate = self
collisionBehavior.setTranslatesReferenceBoundsIntoBoundary(with: .zero)
collisionBehavior.collisionMode = .everything
self.dynamicAnimator?.addBehavior(collisionBehavior)
//Push ball
let pushBehavior = UIPushBehavior(items: [rect], mode: UIPushBehaviorMode.instantaneous)
pushBehavior.active = true
pushBehavior.pushDirection = CGVector(dx: 0.5, dy: 0.5)
self.dynamicAnimator?.addBehavior(pushBehavior)
}
}
extension ViewController: UICollisionBehaviorDelegate {
// DELEGATE METHODS NOT CALLED
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?,
at p: CGPoint) {
print("began contact boundary")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?) {
print("contact boundary ended")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item1: UIDynamicItem,
with item2: UIDynamicItem) {
print("contact item ended")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item1: UIDynamicItem,
with item2: UIDynamicItem,
at p: CGPoint) {
print("began contact item")
}
}
基础 SDK:iOS11.2,Xcode9.2 版 (9C40b)
感谢您的帮助!
这不是它的工作方式(可悲)..你的碰撞行为中只有一个项目,你要求它检测与什么的碰撞???如果您添加了第二个项目,您将看到代理被调用..
真正的问题是为什么?好吧,碰撞检测一个项目的框架是否与另一个项目的框架相交。如果它做了你所要求的(rect
是 physicsView
的 child),那么它总是会发生碰撞(这不是你想要的)..
因为你的 physicsView
不是碰撞行为的一部分,你什么也得不到。你告诉它把项目限制在它的范围内(setTranslatesReferenceBoundsIntoBoundary
对添加到行为的项目起作用本身),但不检测与边界的碰撞。例如,如果项目在 physicsView
之外,则无法进入。如果在内部,则无法退出。但它不会被算作碰撞(否则它总是碰撞)。
为了检测你的 rect
和你的 physicsView
之间的碰撞,你需要给 physicsView
一些物理属性。现在它只是一个普通的 UIView
(参考视图)..
另一种解决必须为其赋予物理属性的方法是为其添加边界:
collisionBehavior.addBoundary(withIdentifier: "PhysicsViewBoundary" as NSString, for: UIBezierPath(rect: physicsView.bounds))
现在它将调用:
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?,
at p: CGPoint) {
print("began contact boundary")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?) {
print("contact boundary ended")
}
我开发了一个应用程序并使用 UIKitDynamics 实现了碰撞检测。
碰撞检测正在运行。但不知何故 UICollisionBehaviorDelegate 方法没有被调用。 未显示任何警告或错误。
我创建了一个示例项目来演示该问题:
import UIKit
class ViewController: UIViewController {
private var dynamicAnimator: UIDynamicAnimator?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.initPhysics()
}
fileprivate var initalized = false
fileprivate func initPhysics() {
if initalized {
return
}
initalized = true
let physicsView = UIView(frame: view.bounds.insetBy(dx: 40, dy: 40))
physicsView.backgroundColor = UIColor.black
self.dynamicAnimator = UIDynamicAnimator(referenceView: physicsView)
physicsView.isUserInteractionEnabled = false
view.addSubview(physicsView)
//Create ball
let frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let rect = UIView(frame: frame)
rect.backgroundColor = UIColor.red
physicsView.addSubview(rect)
let behavior = UIDynamicItemBehavior(items: [rect])
behavior.elasticity = 1.0
behavior.resistance = 0.0
behavior.friction = 0.0
behavior.allowsRotation = false
self.dynamicAnimator?.addBehavior(behavior)
//collision behavior setup
let collisionBehavior = UICollisionBehavior(items: [rect])
collisionBehavior.collisionDelegate = self
collisionBehavior.setTranslatesReferenceBoundsIntoBoundary(with: .zero)
collisionBehavior.collisionMode = .everything
self.dynamicAnimator?.addBehavior(collisionBehavior)
//Push ball
let pushBehavior = UIPushBehavior(items: [rect], mode: UIPushBehaviorMode.instantaneous)
pushBehavior.active = true
pushBehavior.pushDirection = CGVector(dx: 0.5, dy: 0.5)
self.dynamicAnimator?.addBehavior(pushBehavior)
}
}
extension ViewController: UICollisionBehaviorDelegate {
// DELEGATE METHODS NOT CALLED
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?,
at p: CGPoint) {
print("began contact boundary")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?) {
print("contact boundary ended")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item1: UIDynamicItem,
with item2: UIDynamicItem) {
print("contact item ended")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item1: UIDynamicItem,
with item2: UIDynamicItem,
at p: CGPoint) {
print("began contact item")
}
}
基础 SDK:iOS11.2,Xcode9.2 版 (9C40b)
感谢您的帮助!
这不是它的工作方式(可悲)..你的碰撞行为中只有一个项目,你要求它检测与什么的碰撞???如果您添加了第二个项目,您将看到代理被调用..
真正的问题是为什么?好吧,碰撞检测一个项目的框架是否与另一个项目的框架相交。如果它做了你所要求的(rect
是 physicsView
的 child),那么它总是会发生碰撞(这不是你想要的)..
因为你的 physicsView
不是碰撞行为的一部分,你什么也得不到。你告诉它把项目限制在它的范围内(setTranslatesReferenceBoundsIntoBoundary
对添加到行为的项目起作用本身),但不检测与边界的碰撞。例如,如果项目在 physicsView
之外,则无法进入。如果在内部,则无法退出。但它不会被算作碰撞(否则它总是碰撞)。
为了检测你的 rect
和你的 physicsView
之间的碰撞,你需要给 physicsView
一些物理属性。现在它只是一个普通的 UIView
(参考视图)..
另一种解决必须为其赋予物理属性的方法是为其添加边界:
collisionBehavior.addBoundary(withIdentifier: "PhysicsViewBoundary" as NSString, for: UIBezierPath(rect: physicsView.bounds))
现在它将调用:
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?,
at p: CGPoint) {
print("began contact boundary")
}
func collisionBehavior(_ behavior: UICollisionBehavior,
endedContactFor item: UIDynamicItem,
withBoundaryIdentifier identifier: NSCopying?) {
print("contact boundary ended")
}