Ios &引用;推动;匹配UIInterpolingMotionEffect?(即访问UIInterpolingMotionEffect上的“物理”)

Ios &引用;推动;匹配UIInterpolingMotionEffect?(即访问UIInterpolingMotionEffect上的“物理”),ios,accelerometer,physics,gyroscope,uimotion,Ios,Accelerometer,Physics,Gyroscope,Uimotion,使用UIInterpolingMotionEffect,扭曲iPhone,您可以移动图像 现在:想象一下,使用UICollisionBehavior和UIDynamicEmbehavior,您将在屏幕上“反弹”一个红色块。当用户扭转iPhone时:我希望盒子“开始移动”,具有与使用UIInterpolingMotionEffect类似的物理感觉 旁白:UX解释:反弹效果(例如:iPhone上的短信)与iOS中的视差图像效果具有相同的“感觉”。(我所说的“感觉”其实是指相同的速度和加速度。)这将

使用UIInterpolingMotionEffect,扭曲iPhone,您可以移动图像

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

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

现在:使用CMAccelerometerData和使用UIPushBehaviorModeInstance应用推送,实现我所描述的相对简单。但这是一大堆乱七八糟的代码

相比之下,UIInterpolingMotionEffect的使用非常简单

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


类似的想法。。。


它的问题很简单:如何从UIInterpolingMotionEffect轻松“获取”值?也就是说,似乎难以置信的是,我们必须仔细地对CALayer进行子类化,等等。

通过
uiInterpolingMotionEffect
更新某些行为是一个有趣的概念,尽管我不怀疑它是为此而设计的。如果您想根据加速度计信息更新行为,我个人认为
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);
    }
}];
如果您想让它们精确地按照姿态移动,在停止移动设备时停止移动(如
ui插值运动效果
所做的),您可以使用
ui附件行为
,例如:

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
相对于原始方向应用重力。很明显,如果你想的话,你也可以使用预先确定的态度


但是,希望以上说明了解决这种用户体验的一种方法。

是的,我不知道有任何UIKit Dynamics行为链接到加速计,因此您可能仍然需要经历
CMMotionManager
过程。另一方面,我不确定我是否会使用与加速计信息相关的推送,而是会根据
CMMotionManager
信息调整
UIGravityBehavior
UIAttachmentBehavior
。这取决于所需的用户体验。我想,当设备倾斜度超过某个阈值时,你也可以推一推,但这不是我喜欢的用户体验(没有双关语)。你可能会建议如何简化代码,你可能想在你的问题中添加代码的突出部分。这也可能使所需的用户体验更加清晰,因为我很难将“类似于
uiinterpolingmotioneffect
”与
UIPushBehavior
(就像我说的,它更像是一个“变化的附件”,而不是一个“推”)。R。。。(1) 万分感谢重力/附件建议,我将彻底尝试这种方法。(2) 请注意,实际上,关联问题可能是对手头问题的更好表达。(一旦我得到了这些价值观,我很容易“知道该怎么做”;似乎难以置信,要得到这些价值观太难了!)(3)关于“UX价值”——我在问题中加了几个词和视频。可以肯定的是,人们可以看到iOS中的短信推送效应和iOS中的视差bg效应是完全无用和愚蠢的(许多消费者确实感觉到了这一点)。当然,“这只是一种效果。”)关于第3点,我并没有试图对这类效果的价值发表任何贬义声明,而只是说我不清楚在这种特殊情况下,想要的效果到底是什么。Lol.Lol不确定-我加了一个视频!!!!难以置信的示例代码,谢谢!我会试试看,比较一下。出于好奇,我将把我们目前也改进过的代码放进去,它在任何“块盒”上看起来都很棒。答案很好,需要记住一点——“因为处理的事件可能以很高的速率到达,所以不建议使用主操作队列。”同意。您可以使用
deviceMotionUpdateInterval
(如我的第二个示例中所示)或使用后台队列(但如果使用后台队列,则不要掉头将更新发送回主队列;您必须使用调度源或其他机制将UI更新与运动事件解耦)。