如何正确重置UIView的动作效果?

时间:2014-11-19 16:32:17

标签: ios objective-c uiview motion

我已经扩展了UIView类,以便在UIView中实现我自己的快速方法来添加动作效果:

#import "UIView+Extensions.h"

@implementation UIView (Extensions)

// ...

- (void)setMotion:(CGPoint)motion
{
    // Remove all motion effects.
    if (self.motionEffects.count > 0) {

        [self removeMotionEffect:[self.motionEffects objectAtIndex:0]];
        [self removeMotionEffect:[self.motionEffects objectAtIndex:1]];
    }

    // Add motion effects.
    UIInterpolatingMotionEffect *horizontalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
    UIInterpolatingMotionEffect *verticalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];

    [self addMotionEffect:horizontalMotionEffect];
    [self addMotionEffect:verticalMotionEffect];

    // Set motion effect values.
    horizontalMotionEffect.minimumRelativeValue = @(-motion.x);
    horizontalMotionEffect.maximumRelativeValue = @(motion.x);

    verticalMotionEffect.minimumRelativeValue = @(-motion.y);
    verticalMotionEffect.maximumRelativeValue = @(motion.y);
}

我遇到了反直觉的错误。

  

*由于未捕获的异常'NSRangeException'终止应用程序,原因:'* - [__ NSArrayI objectAtIndex:]:索引1超出边界[0 ..   0]”   ***首先抛出调用堆栈:(0x28d3749f 0x3652ec8b 0x28c4bc35 0x7ab1f 0x79e95 0x7d983 0x7a39f 0x6969f 0x7ddf3 0x2c1f9d0f 0x2c1f9a7d   0x2c1ff953 0x2c1fd3bd 0x2c26760d 0x2c45951b 0x2c45b98b 0x2c466209   0x2c45a217 0x2f4c80d1 0x28cfdd7d 0x28cfd041 0x28cfbb7b 0x28c493c1   0x28c491d3 0x2c25e1bf 0x2c258fa1 0x7f425 0x36aaeaaf)libc ++ abi.dylib:   以NSException类型的未捕获异常终止

这意味着这行代码:

[self removeMotionEffect:[self.motionEffects objectAtIndex:0]];

删除两种效果,而不仅仅是第一种效果。

这怎么可能?

这不是最糟糕的部分......

如您所知,将代码更改为:

// Remove all motion effects.
if (self.motionEffects.count > 0) {

    [self removeMotionEffect:[self.motionEffects objectAtIndex:0]]; // Should remove the first, or both but removes the second one.
}

应该解决问题,因为上面的代码行将删除这两个。 它不是。 它实际上删除了垂直效果,第二个! 因此,每次重置动作时,水平轴都会累加起来 越来越快。

这是无法推理的。

3 个答案:

答案 0 :(得分:3)

第一次

之后
[self removeMotionEffect:[self.motionEffects objectAtIndex:0]];

self.motionEffects只包含一个对象,所以你不能使用objectAtIndex:1,因为你会得到越界异常......

使用

[self.motionEffects firstObject]

或一些循环来做...

答案 1 :(得分:1)

实际上,当删除索引为零的对象时,将更改数组中其他项的索引。例如,在索引0处删除对象后,索引1处的项目索引将更改为0.您可以通过在条件 if(self.motionEffects.count> 0)中交换两行来使此代码正常工作)

答案 2 :(得分:0)

Swift 4

extension UIView {
    func stopParallax() {
        for motion in motionEffects {
            removeMotionEffect(motion)
        }
    }
}