I have a small UIView that bounces in a box. I am adding an Instantaneous mode. push. In fact I am adding very many pushes -- 5 or more Hz.
Mystery:
(1) Do I have to removeBehavior???? if so .. when?!? "after" an "instant" ?
(2) Is it that UIPushBehaviorModeInstantaneous is a special case, and you do not have to (or cannot) remove those??
(3) When you addBehavior: does that .. retain?! the UIPushBehavior? Or?? WTF?!
(4) I couldn't seem to find these aspects documented anywhere!
-(void)pushMeRight:(CGFloat)mag
{
if ( self.bounceAnimator == nil ) return;
NSLog(@"...........push me right %.2f", mag);
UIPushBehavior *pushRight = [[UIPushBehavior alloc]
initWithItems:@[self]
mode:UIPushBehaviorModeInstantaneous];
pushRight.magnitude = mag;
pushRight.angle = radians(0); // (NB, 0 is right, 90 is down)
[self.bounceAnimator addBehavior:pushRight];
}
{Note: I simply alloc the UIPushBehavior each time I need one. Note that if you try to use "just one" as a property, it does not work. In fact, Rob explains why below.}
Solution
After extremely extensive testing, we found that Rob's "second" solution, using the .action, is essentially perfect.
Again after vast testing, we would very strongly recommend that the following code, is, really, "the solution", the only way to code repetitive pushes.. Thank goodness for Rob :/
-(void)pushAllUp:(CGFloat)mag
{
if ( self.bounceAnimator == nil ) return;
for ( UIView *pushme in self.subviews )
{
UIPushBehavior *pp =
[[UIPushBehavior alloc]initWithItems:@[ pushme ]
mode:UIPushBehaviorModeInstantaneous];
pp.magnitude = mag;
pp.angle = radians(270); // (NB, 0 is right, 90 is down)
UIPushBehavior __weak *weakPP = pp;
pp.action = ^{ if (!weakPP.active)
[self.bounceAnimator removeBehavior:weakPP];};
[self.bounceAnimator addBehavior:pp];
}
}