我已经扩展了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.
}
应该解决问题,因为上面的代码行将删除这两个。 它不是。 它实际上删除了垂直效果,第二个! 因此,每次重置动作时,水平轴都会累加起来 越来越快。
这是无法推理的。
答案 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)
}
}
}