MKMapRect zooms too much

后端 未结 5 1784
悲哀的现实
悲哀的现实 2021-01-14 11:32

I use this code to show all my annotations on my map:

 MKMapRect zoomRect = MKMapRectNull;
        for (id  annotation in mapView.annotat         


        
相关标签:
5条回答
  • 2021-01-14 11:41

    Ariel's solution wasn't working for me either but n00neimp0rtant's was. I have rewritten it in Swift as a function rectWithMinimumZoom(_ minimumZoom: Double) in an extension of MKMapRect. In return it the adjusted rect (if adjustment is needed). Also I added a extra safety that minimumZoom cannot be divided by 0.

    SWIFT

    extension MKMapRect {
    func rectWithMinimumZoom(_ minimumZoom: Double = 750) -> MKMapRect{
        var needChange = false
    
        var x = MKMapRectGetMinX(self)
        var y = MKMapRectGetMinY(self)
        var w = MKMapRectGetWidth(self)
        var h = MKMapRectGetHeight(self)
        let centerX = MKMapRectGetMidX(self)
        let centerY = MKMapRectGetMidY(self)
    
        if(h < minimumZoom){
            let factor = minimumZoom / max(h,1)
            h = minimumZoom
            w *= factor;
            x = centerX - w / 2
            y = centerY - h / 2
            needChange = true
        }
        if(w < minimumZoom){
            let factor = minimumZoom / max(w,1)
            w = minimumZoom
            h *= factor
            x = centerX - w / 2
            y = centerY - h / 2
            needChange = true
        }
        if(needChange){
            return MKMapRectMake(x, y, w, h);
        }
        return self
    }
    
    0 讨论(0)
  • 2021-01-14 11:49

    For those of us who like one liners:

    let minRectSize: Double = 5000
    zoomRect = MKMapRect(
        x: zoomRect.minX - max(0, minRectSize - zoomRect.width) / 2,
        y: zoomRect.minY - max(0, minRectSize - zoomRect.height) / 2,
        width: max(zoomRect.width, minRectSize),
        height: max(zoomRect.height, minRectSize))
    
    0 讨论(0)
  • 2021-01-14 11:57

    Try this code:

    //here comes your for loop...
    
    double minMapHeight = 10; //choose some value that fit your needs
    double minMapWidth = 10;  //the same as above
    BOOL needChange = NO;
    
    double x = MKMapRectGetMinX(zoomRect);
    double y = MKMapRectGetMinY(zoomRect);
    double w = MKMapRectGetWidth(zoomRect);
    double h = MKMapRectGetHeight(zoomRect);  //here was an error!!
    
    if(MKMapRectGetHeight(zoomRect) < minMapHeight){
        x -= minMapWidth/2;
        w += minMapWidth/2;
        needChange = YES;
    }
    if(MKMapRectGetWidth(zoomRect) < minMapWidth){
        y -= minMapHeight/2;
        h += minMapHeight/2;
        needChange = YES;
    }
    if(needChange){
        zoomRect = MKMapRectMake(x, y, w, h);
    }
    [mapView setVisibleMapRect:zoomRect animated:YES];
    

    EDITED ->

    double minMapHeight = 250; //choose some value that fit your needs
    double minMapWidth = 250;  //the same as above
    BOOL needChange = NO;
    
    double x = MKMapRectGetMinX(zoomRect);
    double y = MKMapRectGetMinY(zoomRect);
    double w = MKMapRectGetWidth(zoomRect);
    double h = MKMapRectGetHeight(zoomRect);
    double centerX = MKMapRectGetMidX(zoomRect);
    double centerY = MKMapRectGetMidY(zoomRect);
    
    if(MKMapRectGetHeight(zoomRect) < minMapHeight){
        //x -= minMapWidth/2;
        //w += minMapWidth/2;
        x = centerX - w/2;
        needChange = YES;
    }
    if(MKMapRectGetWidth(zoomRect) < minMapWidth){
        //y -= minMapHeight/2;
        //h += minMapHeight/2;
        y = centerY - h/2;
        needChange = YES;
    }
    if(needChange){
        zoomRect = MKMapRectMake(x, y, w, h);
    }
    [mapView setVisibleMapRect:zoomRect animated:YES];
    
    0 讨论(0)
  • 2021-01-14 12:00

    In my code, I add extra spacing around, so it will automatically adjust the zoom level in order to fit.

    [aMapView setVisibleMapRect:zoomRect edgePadding:UIEdgeInsetsMake(-100, -50, -50, -50) animated:YES];
    
    0 讨论(0)
  • 2021-01-14 12:06

    Ariel's answer didn't work for me, but I made a few small changes to it and it's working great now (especially with maps with a single pin):

    double minimumZoom = 6000; // for my purposes the width/height have same min zoom
    BOOL needChange = NO;
    
    double x = MKMapRectGetMinX(zoomRect);
    double y = MKMapRectGetMinY(zoomRect);
    double w = MKMapRectGetWidth(zoomRect);
    double h = MKMapRectGetHeight(zoomRect);
    double centerX = MKMapRectGetMidX(zoomRect);
    double centerY = MKMapRectGetMidY(zoomRect);
    
    if (h < minimumZoom) {  // no need to call MKMapRectGetHeight again; we just got its value!
        // get the multiplicative factor used to scale old height to new,
        // then apply it to the old width to get a proportionate new width
        double factor = minimumZoom / h;
        h = minimumZoom;
        w *= factor;
        x = centerX - w/2;
        y = centerY - h/2;
        needChange = YES;
    }
    
    if (w < minimumZoom) {
        // since we've already adjusted the width, there's a chance this
        // won't even need to execute
        double factor = minimumZoom / w;
        w = minimumZoom;
        h *= factor;
        x = centerX - w/2;
        y = centerY - h/2;
        needChange = YES;
    }
    
    if (needChange) {
        zoomRect = MKMapRectMake(x, y, w, h);
    }
    
    [mapView setVisibleMapRect:zoomRect animated:YES];
    
    0 讨论(0)
提交回复
热议问题