【问题标题】:Using IBAction Buttons to Zoom MapView使用 IBAction 按钮缩放 MapView
【发布时间】:2013-02-17 02:45:48
【问题描述】:

我有一个问题。我的当前位置在地图视图中显示并居中,但地图区域不会放大。我尝试通过从 didUpdateToLocation 方法中取出 span 和 region 来接受 Rob 的建议,但我一定没有正确实施它。我认为它没有识别我在 viewDidLoad 中对 setRegion 的调用,并且我的按钮没有被识别。请检查我下面的代码并指出错误。我的目标是能够使用 IBAction 按钮放大和缩小我的位置。

.h

- (IBAction)zoomIn:(id)sender;

- (IBAction)zoomOut:(id)sender;

.m in viewDidLoad

double miles = 0.5;

MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/69.0;

MKCoordinateRegion region;
region.span = span;

[self.mapView setRegion:region animated:YES];

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];

_mapView.mapType = MKMapTypeSatellite;

.m 在我的 didUpdateToLocation 方法中。

[self.mapView setCenterCoordinate:newLocation.coordinate animated:YES];

.放大:

- (IBAction)zoomIn:(id)sender 
{
    MKCoordinateSpan span;
    span.latitudeDelta = _mapView.region.span.latitudeDelta * 2;
    span.longitudeDelta = _mapView.region.span.latitudeDelta * 2;
    MKCoordinateRegion region;
    region.span = span;
    region.center = _mapView.region.center;

    [self.mapView setRegion:region animated:YES];
}

.缩小:

- (IBAction)zoomOut:(id)sender
{
     MKCoordinateSpan span;
     span.latitudeDelta = _mapView.region.span.latitudeDelta / 2;
     span.longitudeDelta = _mapView.region.span.latitudeDelta / 2;
     MKCoordinateRegion region;
     region.span = span;
     region.center = _mapView.region.center;

     [self.mapView setRegion:region animated:YES];
}

【问题讨论】:

    标签: ios ios6 mkmapview zooming ibaction


    【解决方案1】:

    试试这个。但我还没有测试。

    - (IBAction)zoomIn:(id)sender {
          MKCoordinateSpan span;
          span.latitudeDelta = _mapView.region.span.latitudeDelta * 2;
          span.longitudeDelta = _mapView.region.span.latitudeDelta * 2;
          MKCoordinateRegion region;
          region.span = span;
          region.center = _mapView.region.center;
    
         [self.mapView setRegion:region animated:YES];
     }
    
     - (IBAction)zoomOut:(id)sender {
          MKCoordinateSpan span;
          span.latitudeDelta = _mapView.region.span.latitudeDelta / 2;
          span.longitudeDelta = _mapView.region.span.latitudeDelta / 2;
          MKCoordinateRegion region;
          region.span = span;
          region.center = _mapView.region.center;
    
         [self.mapView setRegion:region animated:YES];
    
     }
    

    【讨论】:

    • 感谢您的回复。缩放有效,但缩放区域不会保留。它会迅速恢复到在 didUpdateToLocation 中调用的原始缩放。我认为是因为 didUpdateToLocation 不断更新并在运行时调用原始跨度。您有什么想法可以解决此问题并让缩放视图保持不变吗?
    【解决方案2】:

    您可以获取当前的region,将span乘以或除以2,视情况而定(放大时除,缩小时乘),然后设置region

    - (IBAction)zoomIn:(id)sender {
        MKCoordinateRegion region = self.mapView.region;
        region.span.latitudeDelta /= 2.0;
        region.span.longitudeDelta /= 2.0;
        [self.mapView setRegion:region animated:YES];
    }
    
    - (IBAction)zoomOut:(id)sender {
        MKCoordinateRegion region = self.mapView.region;
        region.span.latitudeDelta  = MIN(region.span.latitudeDelta  * 2.0, 180.0);
        region.span.longitudeDelta = MIN(region.span.longitudeDelta * 2.0, 180.0);
        [self.mapView setRegion:region animated:YES];
    }
    

    如果您想让地图自动缩放到您的位置,您可以使用:

    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
    

    如果您想手动执行此操作,您可以执行以下操作。首先,为您是否已经放大定义一个类属性:

    @property (nonatomic) BOOL alreadySetZoomScale;
    

    然后更改您的didUpdateLocations(或didUpdateToLocation)以检查这一点并设置一次缩放比例:

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation* newLocation = [locations lastObject]; // if less than zero, then valid lat and long not found
    
        if (newLocation.horizontalAccuracy < 0)
            return;
    
        if (!self.alreadySetZoomScale)
        {
            MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1609, 1609); // 1 mile = 1609.34 meters
            self.mapView.region = region;
            [self.mapView setRegion:region animated:YES];
            self.alreadySetZoomScale = YES;
        }
        else
        {
            [self.mapView setCenterCoordinate:newLocation.coordinate animated:YES];
        }
    }
    
    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        // if prior to iOS 6, use this old `MKMapViewDelegate` method, but call our
        // other routine.
    
        if (SYSTEM_VERSION_LESS_THAN(@"6.0"))
            [self locationManager:manager didUpdateLocations:@[newLocation]];
    }
    

    这基本上是说,“如果我还没有放大,请根据newLocation 和该位置周围的一定米数设置区域,但如果我已经这样做了,只需设置中心坐标基于我当前的位置,但不要更改缩放比例(以防我已经放大或缩小)。这也会执行一些条件 iOS 版本号逻辑(使用macros shown here),确保最终用户是运行 6.0 之前的 iOS,它将调用我们更新的方法。

    顺便说一句,如果您要在地图上显示用户位置(例如self.mapView.showsUserLocation = YES;),您可能希望在移动地图中心之前,让这个didUpdateLocations 也删除与MKUserLocation 关联的叠加层,否则它会留下旧的覆盖:

    [self.mapView removeOverlays:self.mapView.overlays];
    

    【讨论】:

    • 这里也一样。请阅读我对 Manu 的评论。感谢您的回复。
    • @user1886166 您在didUpdateToLocation 中设置span。别。做一次(例如,第一次获得位置),在那之后,只需使用MKMapView 方法,setCenterCoordinate,但在那之后不要乱用它。坦率地说,如果您希望您的地图视图在用户移动时跟随他们,那么您可能不应该手动执行此操作。您应该考虑设置MKMapViewuserTrackingMode 属性。
    • 我试了一下,还是不行。请检查并告诉我我做错了什么。抱歉,我对 MKMapView 不是很熟悉,但我明白你在说什么。
    • @user1886166 两件事:1. 你可能想调用一次MKCoordinateRegionMakeWithDistance,这样你就可以放大到正确的初始缩放级别。 2. 在您的缩放按钮上,我认为您有倍数并向后划分(就像 Manu 所做的那样)。无论如何,请参阅我修改后的答案,该答案显示了设置region 第一次位置更新的想法,然后使用centerCoordinate
    • 这几乎行得通!问题是它只设置一次区域,而实际上每次加载视图时都需要这样做。我的应用程序使用导航控制器打开菜单,其中包含不同工具的按钮。选择 Locationing 按钮打开 mapView 并使用功能缩放按钮显示用户位置(完美!)。问题是,当您按回主菜单并重新进入定位时,地图不会缩放回区域,而只会将用户位置设置为中心,因为它之前已经设置了区域。此时我的缩放功能也不起作用。
    【解决方案3】:

    好的,这就是我最终用来让我的 2 个 IBAction 按钮(zoomIn 和 zoomOut)与我的 mapView 一起工作的方法。当您打开应用程序时,会显示用户位置,并且地图会放大并以它为中心。然后,您可以使用按钮放大或缩小 2 倍。*非常感谢 Rob,他为我指明了方向。

    .h

    - (IBAction)zoomIn:(id)sender;
    
    - (IBAction)zoomOut:(id)sender;
    

    .m

    @interface LocationViewController ()
    
    @property (nonatomic) BOOL alreadySetZoomScale;
    
    @end
    
    
    
    -(void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
          fromLocation:(CLLocation *)oldLocation {
    
    
    if (!_alreadySetZoomScale)
    {
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate,    1609, 1609); // 1 mile = 1609.34 meters
    
    self.mapView.region = region;
    [self.mapView setRegion:region animated:YES];
    _alreadySetZoomScale = YES;
    
    }
    
    else
    
    {
    [self.mapView setCenterCoordinate:newLocation.coordinate animated:YES];
    }
    
    
    - (IBAction)zoomIn:(id)sender {
    
    MKCoordinateRegion region = self.mapView.region;
    region.span.latitudeDelta /= 2.0;
    region.span.longitudeDelta /= 2.0;
    self.mapView.region = region;
    
    }
    
    - (IBAction)zoomOut:(id)sender {;
    
    MKCoordinateRegion region = self.mapView.region;
    region.span.latitudeDelta *= 2.0;
    region.span.longitudeDelta *= 2.0;
    self.mapView.region = region;
    
    }
    

    我还有其他几个对 MKMapView 的调用,例如 self.mapView.showsUserLocation = YES;在 viewDidLoad 中,但仅此而已。

    【讨论】:

      【解决方案4】:

      Swift 2.0:

      使用扩展:

      extension MKMapView{
      
       func zoomInPinAnnotationLocation(targetMapViewName : MKMapView?, delta: Double)
       {
        var region: MKCoordinateRegion = targetMapViewName!.region
        region.span.latitudeDelta /= delta
        region.span.longitudeDelta /= delta
        targetMapViewName!.region = region
      
       }
       func zoomOutPinAnnotationLocation(targetMapViewName : MKMapView?,delta: Double)
       {
        var region: MKCoordinateRegion = targetMapViewName!.region
        region.span.latitudeDelta *= delta
        region.span.longitudeDelta *= delta
        targetMapViewName!.region = region
       }
      
      }
      

      用法:

      var mapViewZoomStepperValue: Double = -1.0
      @IBOutlet weak var mapViewZoomStepper: UIStepper!
      
      @IBAction func mapViewZoomStepperValueChanged(sender: AnyObject) {
      
        if (mapViewZoomStepper.value  > mapViewZoomStepperValue)
        {
         mapViewZoomStepperValue = mapViewZoomStepperValue + 1.0
      
      //Zoom In
         detailMapView.zoomInPinAnnotationLocation(detailMapView, delta: 3.0)
        }
        else
        {
         mapViewZoomStepperValue = mapViewZoomStepper.value - 1.0
      
      //Zoom Out
         detailMapView.zoomOutPinAnnotationLocation(detailMapView, delta: 3.0)
        }
      
       }
      

      【讨论】:

        【解决方案5】:

        3行代码就可以实现最基本的

        var region: MKCoordinateRegion = self.mapView.region
        region = MKCoordinateRegionMake(self.mapView.centerCoordinate, MKCoordinateSpanMake(0.005, 0.005));
        self.mapView.setRegion(region, animated: true)
        

        【讨论】:

          【解决方案6】:

          斯威夫特 3:

          import GoogleMaps
          import GooglePlaces
          import CoreLocation
          import UIKit
          
          class LocationMapView: UIViewController, GMSMapViewDelegate, CLLocationManagerDelegate {
          
               @IBOutlet weak var mapView: GMSMapView!
          
               var mapViewZoomStepperValue: Float = 0.0
               @IBOutlet weak var mapViewZoomStepper: UIStepper!
          
               override func viewDidLoad() {
                      super.viewDidLoad()
          
                      mapViewZoomStepper.minimumValue = -100
          
                  }
          
                  @IBAction func mapViewZoomStepperValueChanged(_ sender: Any) {
          
                      if (Float(mapViewZoomStepper.value) > mapViewZoomStepperValue){
          
                          mapViewZoomStepperValue = Float(mapViewZoomStepper.value)
                          zoomIn()
          
                      }else{
          
                          mapViewZoomStepperValue = Float(mapViewZoomStepper.value)
                          zoomOut()
          
                      }
          
                  }
          
                  func zoomIn() {
          
                      print("Zoom in!!")
                      if mapView.camera.zoom == mapView.maxZoom {
                          return
                      }
          
                      let currentZoom = mapView.camera.zoom + 1
                      mapViewZoomController(currentZoom)
          
                  }
          
                  func zoomOut() {
          
                      print("Zoom out!!")
                      if mapView.camera.zoom == mapView.minZoom {
                          return
                      }
          
                      let currentZoom = mapView.camera.zoom - 1
                      mapViewZoomController(currentZoom)
          
                  }
          
                  func mapViewZoomController(_ level: Float) {
          
                      let point: CGPoint = mapView.center
                      let coor: CLLocationCoordinate2D = mapView.projection.coordinate(for: point)
                      let camera = GMSCameraPosition.camera(withLatitude: coor.latitude, longitude: coor.longitude, zoom: Float(level))
                      mapView.animate(to: camera)
          
                  }
          
          }
          

          【讨论】:

            猜你喜欢
            • 2011-10-14
            • 2011-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-12
            • 1970-01-01
            • 1970-01-01
            • 2011-10-10
            相关资源
            最近更新 更多