ios - 如何正确重置UIView的运动效果?

标签 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.
}

应该解决问题,因为上面的代码行将同时删除这两个问题。
它不是。 它实际上消除了垂直效果,第二个效果!
因此,每次您重置运动时,水平轴都会累加并移动
快点,再快一点。

这是没有道理的。

最佳答案

第一次之后

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

self.motionEffects仅包含1个对象,因此您不能使用objectAtIndex:1,因为您将获得超出范围的异常...


[self.motionEffects firstObject]

或一些循环来做...

关于ios - 如何正确重置UIView的运动效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27022012/

相关文章:

ios - 使用 UIPanGestureRecognizer 缩放和移动 UIView

ios - UIView 固定到屏幕边缘,但框架保持 0,0

objective-c - iOS:如何将 "cartoon"风格的动画(电影)添加到幻灯片中?

ios - 仅在 Objective C 中的 UIView 底部的底角半径和阴影

ios - 如何从swift调用 objective-c 中具有处理程序 block 的函数

ios - 在应用程序扩展和容器应用程序之间共享数据

ios - 我的单例可以改进吗?

ios - 为什么 Ios viewPager 与 UISearchController 一起崩溃?

iphone - PSTCollectionView 因 EXC_BAD_ACCESS 崩溃

ios - 如何使用 Storyboard在界面构建器中编辑手动添加的 UINavigationBar subview ?