这是一个有趣的想法,通过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
在后续更新中应用相对于原始方向的重力。显然,如果你愿意的话,你也可以使用预定的态度。
但希望上述内容说明了解决此类用户体验的一种方法。