ios - "pushes"匹配 UIInterpolatingMotionEffect? (即访问 UIInterpolatingMotionEffect 上的 "physics")

标签 ios accelerometer physics gyroscope uimotion

使用 UIInterpolatingMotionEffect,扭转 iPhone,即可让图像移动。

现在:想象一个红色 block ,您将使用 UICollisionBehavior 和 UIDynamicItemBehavior 在屏幕上“弹跳”。当用户扭转 iPhone 时:我希望盒子“开始移动”,并具有与使用 UIInterpolatingMotionEffect 类似的物理感觉。

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

旁白:UX 说明:弹性效果(例如:iPhone 上的短信)与 iOS 中的视差图像效果具有相同的“感觉”。 (我所说的“感觉”实际上只是指相同的速度、加速度。)这将是第三种效果:就像视差一样,它会“稍微移动物体”,但它们会“继续移动”,稍微弹跳。 (你可以说,在某种程度上结合了弹性列表效果和视差图像效果的感觉。)

现在:使用 CMAccelerometerData 并使用 UIPushBehaviorModeInstantaneous 应用推送,执行我所描述的操作相对容易。但这是很多困惑的代码。

相比之下,UIInterpolatingMotionEffect 使用起来极其简单

本质上,我如何从 UIInterpolatingMotionEffect 获取值(然后我将其用作推送)。干杯!


类似的想法...

Simply display the values of UIInterpolatingMotionEffect?

它问得很简单:如何轻松地从 UIInterpolatingMotionEffect 中“获取”值?即,似乎令人难以置信的是,人们必须付出努力来仔细地子类化 CALayer 等。

最佳答案

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

视频剪辑中并不完全清楚所需的用户体验,但看起来视频中的物体继续向手机倾斜的方向滑动,直到您停止倾斜手机。如果这就是您想要的,我倾向于将 CMMotionManager 与 UIKit Dynamics 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更新以应用相对于原始方向的重力。显然,如果你愿意的话,你也可以使用预定的态度。

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

关于ios - "pushes"匹配 UIInterpolatingMotionEffect? (即访问 UIInterpolatingMotionEffect 上的 "physics"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25809318/

相关文章:

java - 计算时差的最可靠方法

java - 如何在JmonkeyEngine3中通过物理控制旋转空间?

c# - 转换为 3D 后速度反射不再起作用

ios - 在 AVMutableVideoComposition 中使用 trackId

iphone - 在我的Movieplayer应用程序中使用加速度计

iphone - 构建的应用程序成功,但无法在我的 iPhone 设备上启动

ios - iOS 加速计游戏录制片段

physics - 如何模拟二维水面?

ios - 如何取消订阅 RxSwift 中的 Observable?

单独 Controller 中的 iOS admob 横幅 - testDevices id 最佳实践?