I'm learning about the UIDynamicAnimator (very cool!) and have set up a test project. I've got things working but it doesn't appear that the density of my objects is taken into account in the physics of the UIFieldBehavior.linearGravityField(_:).
In the documentation for UIDynamicItemBehavior.density it says:
A dynamic item’s relative density, along with its size, determines its effective mass when it participates in UIKit Dynamics behaviors
And the docs for UIFieldBehavior.linearGravityField(_:):
This field creates a directional gravitational force that applies uniformly to all dynamic items with mass.
And
The force on a given item can be determined by the equation F = ma, where force equals the mass of the item multiplied by the acceleration imposed by the gravitational field, which with this type of field is constant.
So my understanding is the density I give to items should affect their physics. This isn't happening - they all fall at exactly the same rate:
Here's my code.
Main VC:
class MainViewController: UIViewController {
var item1: Item!
var item2: Item!
var item3: Item!
var animator: UIDynamicAnimator?
var collision: UICollisionBehavior?
var field: UIFieldBehavior?
override func viewDidLoad() {
super.viewDidLoad()
self.animator = UIDynamicAnimator(referenceView: self.view)
self.animator?.isDebugEnabled = true
self.collision = UICollisionBehavior()
self.field = UIFieldBehavior.linearGravityField(direction: CGVector(dx: 0, dy: 1))
field?.strength = 2.5
self.collision?.translatesReferenceBoundsIntoBoundary = true
if let collision = self.collision {
self.animator?.addBehavior(collision)
}
if let field = self.field {
self.animator?.addBehavior(field)
}
self.item1 = Item()
self.item2 = Item()
self.item3 = Item()
self.item1.mainViewController = self
self.item2.mainViewController = self
self.item3.mainViewController = self
self.item1.configure(x: 50, y: 50, density: 0.1)
self.item2.configure(x: 150, y: 50, density: 100)
self.item3.configure(x: 300, y: 50, density: 10000)
self.animator?.behaviors.forEach( { behavior in
print("")
print(behavior)
})
}}
And the Item class that I'm using to create my objects to get all physic'd up:
class Item: UIImageView {
var itemBehavior: UIDynamicItemBehavior!
var mainViewController: MainViewController?
var randomFloat: CGFloat {
return CGFloat.random(in: 25...50)
}
func configure(x: CGFloat, y: CGFloat, density: CGFloat) {
guard let mainViewController = self.mainViewController else {
return
}
self.layer.backgroundColor = UIColor.red.cgColor
self.layer.frame = CGRect(x: x, y: y, width: self.randomFloat, height: self.randomFloat)
self.itemBehavior = UIDynamicItemBehavior()
self.itemBehavior.density = density
self.itemBehavior.elasticity = 0
self.itemBehavior.allowsRotation = true
self.itemBehavior.friction = 1
self.itemBehavior.addItem(self)
mainViewController.view.addSubview(self)
mainViewController.field?.addItem(self)
mainViewController.collision?.addItem(self)
mainViewController.animator?.addBehavior(self.itemBehavior)
}}
In the debug console I can see that these objects do indeed have a density (of 0.1, 100, and 10000 respectively), it just doesn't seem to affect things at all:
<UICollisionBehavior: 0x600000949b00> (All) (Reference Bounds) (3 items: [iPhone_X_UI_test.Item:0x7fc5e9807f30, iPhone_X_UI_test.Item:0x7fc5e98085a0, iPhone_X_UI_test.Item:0x7fc5e98087e0])
<UIFieldBehavior: 0x6000018640a0>
<UIDynamicItemBehavior: 0x60000154d980> E=0.000000 F=1.000000 D=0.100000 (1 items: [iPhone_X_UI_test.Item:0x7fc5e9807f30])
<UIDynamicItemBehavior: 0x60000154db80> E=0.000000 F=1.000000 D=100.000000 (1 items: [iPhone_X_UI_test.Item:0x7fc5e98085a0])
<UIDynamicItemBehavior: 0x60000154dd00> E=0.000000 F=1.000000 D=10000.000000 (1 items: [iPhone_X_UI_test.Item:0x7fc5e98087e0])
What am I missing or not understanding? I needs me some apparent mass!
Thank you...