Вращение UIView с использованием UIDynamics и силы тяжести из CMMotionManager

У меня есть UIView, который представляет собой рамку для фотографий, висящую на гвозде от веревки. Я пытаюсь повернуть вид вокруг своей точки привязки, чтобы нижняя часть вида была плоской (параллельно земле) независимо от вращения устройств. Я пытаюсь добиться этого с помощью CMMotionManager и UIDynamics и, похоже, сегодня не могу ничего сделать должным образом. Вот код...

- (void)viewDidLoad
{
[super viewDidLoad];

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

CGRect pictureFrameBounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.view.bounds)/2.5f, CGRectGetHeight(self.view.bounds)/5);
UIView *pictureFrame = [[UIView alloc] initWithFrame:pictureFrameBounds];
[pictureFrame setBackgroundColor:[UIColor redColor]];
[self.view addSubview:pictureFrame];

self.gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[pictureFrame]];

self.collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[pictureFrame]];
[self.collisionBehavior setTranslatesReferenceBoundsIntoBoundary:YES];
[self.animator addBehavior:self.collisionBehavior];

CGPoint anchorPoint = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetHeight(self.view.bounds)/8);
self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:pictureFrame
                                                    offsetFromCenter:UIOffsetMake(0.0f, -CGRectGetHeight(pictureFrame.bounds)/2.5f)
                                                    attachedToAnchor:anchorPoint];
[self.attachmentBehavior setDamping:0];
[self.attachmentBehavior setLength:0];
[self.attachmentBehavior setFrequency:0];
[self.animator addBehavior:self.attachmentBehavior];

UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[pictureFrame]];
[itemBehavior setAllowsRotation:YES];
[self.animator addBehavior:itemBehavior];

NSOperationQueue* motionQueue = [NSOperationQueue new];

 self.motionManager = [[CMMotionManager alloc] init];
[self.motionManager startDeviceMotionUpdatesToQueue:motionQueue
                                        withHandler:^(CMDeviceMotion *motion, NSError *error) {
                                           [self.gravityBehavior setGravityDirection:CGVectorMake(motion.gravity.x, motion.gravity.y)];
                                        }];
}

Я пробовал motion.gravity.x в качестве angularForce на itemBehavior, чтобы проверить, что силы возвращаются правильно, и представление вращается в правильном направлении, что, кажется, все в порядке. Проблема с этим подходом состоит в том, что представление продолжает вращаться, так как здесь применяется постоянная сила. Использование setGravityDirection: результаты с привязкой представления без поворота. Некоторая помощь будет высоко ценится! Спасибо!

1 ответ

Попытайтесь изменить NSOperationQueue на mainQueue. Это помогло мне.

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
[self.gravityBehavior setGravityDirection:CGVectorMake(motion.gravity.x, -(motion.gravity.y))];
}];

Надеюсь, это вам тоже помогло.

Другие вопросы по тегам