【问题标题】:Creating compass for app but compass not working if Orientation changes为应用程序创建指南针,但如果方向改变,指南针不起作用
【发布时间】:2014-01-14 12:31:04
【问题描述】:

我正在将指南针构建到我正在开发的 IOS 应用程序中。目前我正在 iPad 上构建,但在视图中切换方向时面临一个巨大的问题

如果我在应用程序已经处于横向/纵向模式时打开视图,则指南针看起来非常好(如第一张图像)但是如果我进入纵向模式然后转向横向,则指南针的整个 UI发疯了(见第二张图片)

我在 ViewDidLoad 中的代码如下所示:

//start updating compass
locationManager=[[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.headingFilter = 1;
locationManager.delegate=self;
[locationManager startUpdatingHeading];

//get coords of current location
CLLocation *location = [locationManager location];
CLLocationCoordinate2D fromLoc = [location coordinate];

//mecca:
CLLocationCoordinate2D toLoc = [location coordinate];
toLoc = CLLocationCoordinate2DMake(21.4167, 39.8167);


//calculate the bearing between current location and Mecca

float fLat = degreesToRadians(fromLoc.latitude);
float fLng = degreesToRadians(fromLoc.longitude);
float tLat = degreesToRadians(toLoc.latitude);
float tLng = degreesToRadians(toLoc.longitude);

float degree = radiandsToDegrees(atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)));

if (degree >= 0) {
    bearing  = degree;
} else {
    bearing = degree+360;
}
NSLog(@"bearing: %f", bearing);

//rotate the needle from true north
float MnewRad =  degreesToRadians(bearing);
needleImage.transform = CGAffineTransformMakeRotation(MnewRad);//rotate the number of degrees from north

}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {

//compass
float oldRad =  -manager.heading.trueHeading * M_PI / 180.0f;
float newRad =  -newHeading.trueHeading * M_PI / 180.0f;

CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation"];
theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
theAnimation.toValue=[NSNumber numberWithFloat:newRad];
theAnimation.duration = 0.3f;
[compassView.layer addAnimation:theAnimation forKey:@"animateMyRotation"];
compassView.transform = CGAffineTransformMakeRotation(newRad);

}

非常感谢您对此的帮助,因为它让我发疯!谢谢

【问题讨论】:

    标签: ios objective-c xcode ipad storyboard


    【解决方案1】:

    didUpdateHeading 每秒被调用多次,所以这里不需要任何动画。我怀疑您没有看到由于0.3f 第二个动画滞后而导致的任何问题。直接将角度旋转设置为新值,它仍然看起来很平滑。

    【讨论】:

    • 感谢您的帮助。那么我应该从我的代码中具体编辑/删除什么?
    • 去掉CABasicAnimation,直接在compassView.layer上自己设置调整后的旋转变换
    【解决方案2】:

    我正在为另一个应用程序制作 Qibla 功能,并且遇到了指南针问题,但我不得不说您的问题与指南针功能完全无关。

    您说过,当您旋转设备时,视图会变得混乱。这似乎是一个明显的视图布局问题。根据您是否使用自动布局,我至少建议您首先将所有指南针视图添加到单个视图容器中。该视图应具有固定大小并在视图中居中。 (又名UIAutoResizingMaskFlexibleTopMarginBottomMarginRightMarginLeftMargin)。

    然后,我不确定旋转是否适合您,但我使用 transform.rotation.z,因为旋转发生在 z 轴上。

    最后,我建议您将动画持续时间设置为位置更新周期,即持续时间 = 0.1 或其他值

    顺便说一句,我从使用CoreLocation 切换到CoreMotion。它有一个更简单的指南针 API,并且对资源的要求要少得多。


    如果您需要查看代码,这是我使用 CoreLocation 的旧代码:

    - (int)fixOrientation {
        switch ([[UIApplication sharedApplication] statusBarOrientation]) {
            case UIInterfaceOrientationPortrait:
                return 0;
            case UIInterfaceOrientationLandscapeLeft:
                return 90;
            case UIInterfaceOrientationLandscapeRight:
                return 270;
            case UIInterfaceOrientationPortraitUpsideDown:
                return 180;
        }
    }
    
    CLHeading* newHeading = [MCLocationTracker sharedTracker].currentHeading;
    
    [self dismissAlert];
    
    float headingFloat = - newHeading.magneticHeading;
    orientationCorrection = [self fixOrientation];
    double angle = [[MCLocationTracker sharedTracker] qiblaBearing];
    
    [UIView animateWithDuration:0.05f
                          delay:0.f
                        options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState)
                     animations:^{
                         self.compassImage.transform = CGAffineTransformMakeRotation(toRadian((headingFloat + orientationCorrection)));
                         if (fabs(kMCLocTrackerUndefinedAngle - angle) > 0.1f) {
                             self.arrow.transform = CGAffineTransformMakeRotation(toRadian((headingFloat+angle) + orientationCorrection));
                         }
                     } 
                     completion:NULL];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-18
      • 2011-05-07
      • 1970-01-01
      相关资源
      最近更新 更多