Я пытаюсь заставить CoreMotion работать правильно, когда устройство пользователя находится в ландшафтном режиме.Приведенный ниже код работает для портретного режима, но я не могу понять, как преобразовать его в альбомную левую и альбомную правую.Если вы знакомы с Quaternions и CoreMotion, любая помощь будет принята с благодарностью.
Проблема: Существует ScrollView, который содержит вид изображения, этот вид изображения можно увидеть только частично влюбой данный момент, и раскрывается, когда пользователь поворачивает свой телефон, чтобы нацелиться на него.Представьте себе, что вы сидите в первом ряду кинотеатра и поворачиваете голову во всех направлениях, чтобы увидеть весь экран.
Я использую кватерион для переменной рыскания, потому что истинное «рыскание» от позиции, кажется,например, если телефон держался ровно.
При повороте телефона в любом из альбомных режимов мне нужно знать уравнения кватериона, чтобы рассчитать правильные градусы для изображения и устройства.
// set content offset for image inside scrollview
CGFloat offsetX;
if (self.deviceDegreesZ >= 180) {
offsetX = (_maximumXOffset/2) + (_maximumXOffset/2) * (fabs(self.deviceDegreesZ - 180))/90;
} else {
offsetX = (_maximumXOffset/2) - (_maximumXOffset/2) * (fabs(self.deviceDegreesZ - 180))/90;
}
CGFloat offsetY;
if (self.deviceDegreesY >= 90) {
offsetY = (_maximumYOffset/2) + (_maximumYOffset/2) * (fabs(self.deviceDegreesY - 90))/45;
} else {
offsetY = (_maximumYOffset/2) - (_maximumYOffset/2) * (fabs(self.deviceDegreesY - 90))/45;
}
if (offsetX != 0 && offsetY != 0) {
[_scrollView setContentOffset:CGPointMake(offsetX, offsetY) animated:NO];
}
// device angles used to set content offset above and look at imageview
// Quaternion
CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
int thePitch = self.motionManager.deviceMotion.attitude.pitch * (180.0 / M_PI);
int theRoll = self.motionManager.deviceMotion.attitude.roll * (180.0 / M_PI);
int theYaw = radiansToDegrees(asin(2*(quat.x*quat.z - quat.w*quat.y)));
// gravity
CMAcceleration gravity = self.motionManager.deviceMotion.gravity;
double rotation = atan2(gravity.x, gravity.y) - M_PI;
self.imageView.transform = CGAffineTransformMakeRotation(rotation);
// portrait (working)
if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationPortrait){
// X
if (quat.y >= 0.5f) {
self.deviceDegreesZ = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
} else if (quat.y <= -0.5f) {
self.deviceDegreesZ = 360 + radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
} else {
self.deviceDegreesZ = 180 - radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
}
// Y
CMAcceleration gravity = self.motionManager.deviceMotion.gravity;
if (gravity.z >= 0) {
self.deviceDegreesY = thePitch; // - abs(theYaw)
} else {
self.deviceDegreesY = 180.f - thePitch; // - abs(theYaw)
}
}
// landscape left
if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationLandscapeLeft){
// ???
}
// landscape right
if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationLandscapeRight){
// ???
}