我应该删除行为UIPushBehavior - 我正在添加许多推送

时间:2014-09-03 14:23:48

标签: ios uikit-dynamics uidynamicbehavior

我有一个小的UIView在一个盒子里弹跳。我正在添加瞬时模式。推。实际上我正在添加很多推 - 5或更多Hz。

推理:

(1)我是否必须 removeBehavior ???? 如果是这样.. 何时?!? “之后”是“瞬间”?

(2)难道UIPushBehaviorModeInstantaneous是一个特例,你不必(或不能)删除那些??

(3)当你添加行为:这样做..保留?! UIPushBehavior?要么?? WTF?!

(4)我似乎无法在任何地方找到这些方面!

-(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];
    }

{注意:我每次只需分配UIPushBehavior 我需要一个。请注意,如果您尝试使用“仅一个”作为属性,则不起作用。事实上,Rob在下面解释了原因。}


解决方案

经过极为广泛的测试后,我们发现使用.action的Rob的“第二”解决方案基本上是完美的。

经过大量测试后,我们强烈建议以下代码,实际上,“解决方案”,这是编写重复推送的唯一方法。感谢Rob的好意:/ < / p>

-(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];
        }
    }

1 个答案:

答案 0 :(得分:6)

回答你的问题:

  1. 是的,您正在正确添加UIPushBehavior

  2. 从技术上讲,您无需拨打removeBehavior进行即时推送,因为一旦发生瞬时推送,该行为的active状态就会被关闭。

    话虽如此,我倾向于消除这种行为,因为你正在以其他方式占用记忆,动画师保持对这些非active瞬时推动行为的强烈参考。 (这可以通过记录动画师的behaviors属性来轻松验证,该属性是它正在跟踪的所有行为的数组。)最终可能存在与性能相关的问题,以便迭代所有这些非active行为也是如此,尽管我怀疑记忆问题可能更为重要。

    但与保留UISnapBehavior的其他行为(例如active)不同,您不必担心延迟的瞬时推送行为会继续影响其添加的项目。

  3. 他们没有“过期”,本身,但是,是的,他们很快就会转到active NO状态。

  4. 是的,当您向动画师添加行为时,动画师将保留对它的强引用,直到您删除该行为。

  5. 就个人而言,我倾向于在添加后删除行为。因为它是瞬间的,它的移除时间并不是非常关键,你可以做一些简单的事情:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self.animator removeBehavior:push];
    });
    

    或者,您可以设置一个action,为您删除它。

    UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:self.items mode:UIPushBehaviorModeInstantaneous];
    push.pushDirection = ...
    
    UIPushBehavior __weak *weakPush = push;  // avoid strong reference cycle
    push.action = ^{
        if (!weakPush.active) {
            [self.animator removeBehavior:weakPush];
        }
    };
    
    [self.animator addBehavior:push];