“推”匹配UIInterpolatingMotionEffect? (即在UIInterpolatingMotionEffect上访问“physics”)

时间:2014-09-12 13:19:32

标签: ios accelerometer physics gyroscope uimotion

使用UIInterpolatingMotionEffect,扭转iPhone,您可以移动图像。

现在:设想一个红色的区块,你会"反弹"在屏幕上,使用UICollisionBehavior和UIDynamicItemBehavior。当用户扭动iPhone时:我想让盒子开始移动"与SIMILAR PHYSICS FEEL一样使用UIInterpolatingMotionEffect。

http://tinypic.com/player.php?v=b67mlc%3E&s=8#.VBVEq0uZNFx

旁白:用户体验解释:弹性效果(例如:iPhone上的短信)具有相同的感觉"作为iOS中的视差图像效果。 (通过"感觉"我真的只是意味着相同的速度,加速度。)这将是第三个效果:像视差一样,它会轻微地移动东西"但是他们会继续前进#34;弹跳一点。 (你可以说,有点结合了弹性列表效应和视差图像效果的感觉。)

现在:使用CMAccelerometerData执行我所描述的操作并使用UIPushBehaviorModeInstantaneous进行推送相对容易。但它的代码很乱。

相比之下,UIInterpolatingMotionEffect使用非常容易

基本上,我如何从UIInterpolatingMotionEffect中获取值(我将使用它作为推送)。干杯!


类似的想法......

Simply display the values of UIInterpolatingMotionEffect?

它简单地问:一个人如何能够轻松地获得"来自UIInterpolatingMotionEffect的值?也就是说,似乎不可思议的是必须努力仔细地继承CALayer等等。

1 个答案:

答案 0 :(得分:3)

这是一个有趣的概念,通过UIInterpolatingMotionEffect更新一些行为,但我并不怀疑它是为此而设计的。如果您想根据加速度计信息更新行为,我个人会认为CMMotionManager非常适合此目的。

视频剪辑并不完全清楚所需的用户体验,但看起来视频会让手机在手机倾斜的方向上继续滑动,直到您停止倾斜手机。如果这就是你想要的,我倾向于将CMMotionManager与UIKit动态UIGravityBehavior结婚:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:container];

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:container.subviews];
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:container.subviews];
gravity.gravityDirection = CGVectorMake(0, 0);
[self.animator addBehavior:gravity];

self.motionManager = [[CMMotionManager alloc] init];

typeof(self) __weak weakSelf = self;

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
    if (weakSelf.referenceAttitude == nil) {
        weakSelf.referenceAttitude = motion.attitude;
    } else {
        CMAttitude *attitude = motion.attitude;
        [attitude multiplyByInverseOfAttitude:weakSelf.referenceAttitude];
        gravity.gravityDirection = CGVectorMake(attitude.roll * 5.0, attitude.pitch * 5.0);
    }
}];

如果您希望它们根据姿势精确移动,停止移动设备时停止移动(如UIInterpolatingMotionEffect那样),您可以使用UIAttachmentBehavior,例如:

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:viewToAttachTo attachedToAnchor:viewToAttachTo.center];
[self.animator addBehavior:attachment];

self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.0 / 20.0;

typeof(self) __weak weakSelf = self;

CGPoint originalAnchorPoint = viewToAttachTo.center;

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
    if (weakSelf.referenceAttitude == nil) {
        weakSelf.referenceAttitude = motion.attitude;
    } else {
        CMAttitude *attitude = motion.attitude;
        [attitude multiplyByInverseOfAttitude:weakSelf.referenceAttitude];
        attachment.anchorPoint = CGPointMake(originalAnchorPoint.x + attitude.roll * 10.0, originalAnchorPoint.y + attitude.pitch * 10.0);
    }
}];

请注意,在这两个示例中,当用户启动应用时,当设备从设备的方向移动时,我正在对行为应用调整。因此,当用户启动应用时,我会捕获CMAttitude属性referenceAttitude作为设备的态度,然后在后续更新中使用multiplyByInverseOfAttitude来应用与原始应用相关的重力取向。显然,如果你愿意,你可以使用预先确定的态度。

但希望上面说明了解决此类用户体验的一种方法。