使用 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/