Swift Mapkit - 远离用户位置

时间:2022-06-01 21:37:36

I want to display user location and the surrounding area, but I also want to allow the user to pan around the area. Right now if I try to scroll somewhere else on the map it automatically takes me back to the base region with the user at the center. How do I stop this? I want to show the initial view with the user in the center, but I want to be able to scroll around too. Thanks in advance you guys are so helpful!

我想显示用户位置和周围区域,但我也想让用户在该区域内平移。现在,如果我尝试在地图上的其他位置滚动,它会自动将我带回到基本区域,用户位于中心。我怎么阻止这个?我想在中心显示用户的初始视图,但我希望能够滚动。在此先感谢您们的帮助!

import UIKit import MapKit import CoreLocation

导入UIKit导入MapKit导入CoreLocation

class ViewControllerMain: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

class ViewControllerMain:UIViewController,MKMapViewDelegate,CLLocationManagerDelegate {

@IBOutlet weak var mapView: MKMapView!

var locationManager:CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
    locationManager = CLLocationManager()
    locationManager.requestWhenInUseAuthorization()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.delegate = self
    locationManager.startUpdatingLocation()
    mapView.showsUserLocation = true
    mapView.delegate = self

    let longPress = UILongPressGestureRecognizer(target: self, action: "action:")
    longPress.minimumPressDuration = 1.0
    mapView.addGestureRecognizer(longPress)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    let regionToZoom = MKCoordinateRegionMake(manager.location.coordinate, MKCoordinateSpanMake(0.01, 0.01))
    mapView.setRegion(regionToZoom, animated: true)
}

3 个解决方案

#1


5  

Your code in didUpdateLocations is resetting the region. You have two options.

您在didUpdateLocations中的代码正在重置该区域。你有两个选择。

  1. Store in an ivar whether or not you have already set the first location. Only if you haven't do you then set the region.

    无论您是否已经设置了第一个位置,都要存放在ivar中。只有你没有这样做,然后设置区域。

  2. Set a timer that runs for 15 seconds. If the map is moved by the user you reset the timer. When the timer expires you can recenter to the users location.

    设置一个运行15秒的计时器。如果用户移动了地图,则重置计时器。当计时器到期时,您可以重新定位到用户位置。

This will keep the map centred around the user but will enable them to pan around a bit to get some context.

这将使地图以用户为中心,但会让他们平移一点以获得一些上下文。

This answer shows how to do it in Objective-C

这个答案显示了如何在Objective-C中完成它

#2


2  

locationManager.stopUpdatingLocation();

this is all you need at end of locationManager fun, if you are still looking for

如果您还在寻找,这就是您在locationManager乐趣结束时所需要的一切

#3


0  

This thread had a good example in both Swift and Obj C. Be sure to look for the comment on the answer I've linked to if you use Swift.

这个帖子在Swift和Obj C中都有一个很好的例子。如果你使用Swift,请务必查看我已链接到的答案的评论。

After you set that up, use Control Flow within the didUpdateLocations, so that it re-centers the user's location only if the user has not touched the map.

设置完成后,在didUpdateLocations中使用Control Flow,这样只有当用户没有触摸地图时,它才会重新定位用户的位置。

Here is my full code as an example:

以下是我的完整代码示例:

@IBOutlet weak var theMap: MKMapView!

// ... 


// This var and the three following functions are used to tell if the map moves because of the user. 
// This is used in the control flow in didUpdateLocations

private var mapChangedFromUserInteraction = false


private func mapViewRegionDidChangeFromUserInteraction() -> Bool {
    let view: UIView = self.theMap.subviews[0] as UIView
    //  Look through gesture recognizers to determine whether this region change is from user interaction
    if let gestureRecognizers = view.gestureRecognizers {
        for recognizer in gestureRecognizers {
            if( recognizer.state == UIGestureRecognizerState.Began || recognizer.state == UIGestureRecognizerState.Ended ) {
                return true
            }
        }
    }
    return false
}

func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    mapChangedFromUserInteraction = mapViewRegionDidChangeFromUserInteraction()
    if (mapChangedFromUserInteraction) {
        // user changed map region
        println("user changed map region")


    }
}

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    if (mapChangedFromUserInteraction) {
        // user changed map region

        println("user changed map region")


    }
}

// This function is called each time the user moves.  
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {




// Use Control Flow: if the user has moved the map, then don't re-center.
// NOTE: this is using 'mapChangedFromUserInteraction' from above. 

    if mapChangedFromUserInteraction == true {

        // do nothing, because the user has moved the map.

    }

    else {

        // update on location to re-center on the user.

        // set X and Y distances for the span (zoom). This is very zoomed in.
        let spanX = 0.0005
        let spanY = 0.0005

        // Create a region using the user's location, and the zoo. 
        var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))

        // set the map to the new region
        theMap.setRegion(newRegion, animated: true)

        }

}

#1


5  

Your code in didUpdateLocations is resetting the region. You have two options.

您在didUpdateLocations中的代码正在重置该区域。你有两个选择。

  1. Store in an ivar whether or not you have already set the first location. Only if you haven't do you then set the region.

    无论您是否已经设置了第一个位置,都要存放在ivar中。只有你没有这样做,然后设置区域。

  2. Set a timer that runs for 15 seconds. If the map is moved by the user you reset the timer. When the timer expires you can recenter to the users location.

    设置一个运行15秒的计时器。如果用户移动了地图,则重置计时器。当计时器到期时,您可以重新定位到用户位置。

This will keep the map centred around the user but will enable them to pan around a bit to get some context.

这将使地图以用户为中心,但会让他们平移一点以获得一些上下文。

This answer shows how to do it in Objective-C

这个答案显示了如何在Objective-C中完成它

#2


2  

locationManager.stopUpdatingLocation();

this is all you need at end of locationManager fun, if you are still looking for

如果您还在寻找,这就是您在locationManager乐趣结束时所需要的一切

#3


0  

This thread had a good example in both Swift and Obj C. Be sure to look for the comment on the answer I've linked to if you use Swift.

这个帖子在Swift和Obj C中都有一个很好的例子。如果你使用Swift,请务必查看我已链接到的答案的评论。

After you set that up, use Control Flow within the didUpdateLocations, so that it re-centers the user's location only if the user has not touched the map.

设置完成后,在didUpdateLocations中使用Control Flow,这样只有当用户没有触摸地图时,它才会重新定位用户的位置。

Here is my full code as an example:

以下是我的完整代码示例:

@IBOutlet weak var theMap: MKMapView!

// ... 


// This var and the three following functions are used to tell if the map moves because of the user. 
// This is used in the control flow in didUpdateLocations

private var mapChangedFromUserInteraction = false


private func mapViewRegionDidChangeFromUserInteraction() -> Bool {
    let view: UIView = self.theMap.subviews[0] as UIView
    //  Look through gesture recognizers to determine whether this region change is from user interaction
    if let gestureRecognizers = view.gestureRecognizers {
        for recognizer in gestureRecognizers {
            if( recognizer.state == UIGestureRecognizerState.Began || recognizer.state == UIGestureRecognizerState.Ended ) {
                return true
            }
        }
    }
    return false
}

func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    mapChangedFromUserInteraction = mapViewRegionDidChangeFromUserInteraction()
    if (mapChangedFromUserInteraction) {
        // user changed map region
        println("user changed map region")


    }
}

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    if (mapChangedFromUserInteraction) {
        // user changed map region

        println("user changed map region")


    }
}

// This function is called each time the user moves.  
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {




// Use Control Flow: if the user has moved the map, then don't re-center.
// NOTE: this is using 'mapChangedFromUserInteraction' from above. 

    if mapChangedFromUserInteraction == true {

        // do nothing, because the user has moved the map.

    }

    else {

        // update on location to re-center on the user.

        // set X and Y distances for the span (zoom). This is very zoomed in.
        let spanX = 0.0005
        let spanY = 0.0005

        // Create a region using the user's location, and the zoo. 
        var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))

        // set the map to the new region
        theMap.setRegion(newRegion, animated: true)

        }

}