Swift + didUpdateUserLocation не вызывается
Я не могу позвонить MKMapView
метод делегата didUpdateUserLocation
,
Что я сделал до сих пор:
Добавить рамки
MapKit.framwork
в проектеИмпортировать структуру в контроллере представления
import MapKit
линияДобавить ключ в файл plist
<key>NSLocationAlwaysUsageDescription</key> <true/>
Код в поле зрения контроллера
Добавлен делегат didUpdateUserLocation
метод проверки местоположения обновлен или нет, но никогда не вызывается.
// MARK: - MapView delegate methods
func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) {
// Calling...
}
func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
// Not getting called
}
// MARK: - View lifeCycle methods
override func viewDidLoad() {
super.viewDidLoad()
var locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
self.mapView.delegate = self
self.mapView.showsUserLocation = true
self.mapView.pitchEnabled = true
self.mapView.showsBuildings = true
}
Я использовал симулятор и изменил собственное местоположение симулятора, чтобы проверить, вызывается он или нет? Метод regionDidChangeAnimated
называется отлично!
То же самое работает для iOS7. какие дополнительные усилия остаются для обновления местоположения на карте Swift?
Изменить: ключи Plist
Также разрешение оповещения не запрашивается.
6 ответов
- Вы должны сохранить ссылку на
CLLocationManager
, - Вам придется подождать
locationManager(_:didChangeAuthorizationStatus:)
вызванный метод делегата.startUpdatingLocation()
а такжеshowsUserLocation = true
, - Согласно документу:
NSLocationWhenInUseUsageDescription
Тип значения - Строка.
Пытаться:
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
// MARK: - View lifeCycle methods
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.mapView.delegate = self
self.mapView.pitchEnabled = true
self.mapView.showsBuildings = true
}
// MARK: - LocationManager delegate methods
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .Authorized, .AuthorizedWhenInUse:
manager.startUpdatingLocation()
self.mapView.showsUserLocation = true
default: break
}
}
// MARK: - MapView delegate methods
func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
println(userLocation)
// Not getting called
}
}
Помимо других ответов я хочу обобщить здесь:
Вы положили ключ NSLocationAlwaysUsageDescription
в вашем info.plist
, value
для этого ключа должна быть строка, содержащая текст вопроса, когда система попросит пользователя запросить разрешение служб определения местоположения.
Согласно ключу, вы должны запросить разрешение по телефону
locationManager.requestWhenInUseAuthorization()
Возможно, вы ответили на вопрос, поэтому ваш ответ может быть уже сохранен в настройках пользователя. Лучший способ - полностью удалить приложение из симулятора и переустановить его, чтобы вас снова спросили.
Проблема в том, что вы запрашиваете разрешение на использование
locationManager.requestWhenInUseAuthorization()
и в pList вы добавляете <key>NSLocationAlwaysUsageDescription</key>
что для всегда авторизации. Вам нужно использовать NSLocationWhenInUseUsageDescription
ключ
Для приложений, работающих на iOS 8, вам нужно добавить два ключа в файл plist:
NSLocationAlwaysUsageDescription (у вас уже есть этот)
NSLocationWhenInUseUsageDescription
Также вам нужно будет завершить проверку, если приложение работает под iOS8, и если это так, добавьте две строки ниже. Если это iOS 7 или ниже, вам нужно пропустить эти две строки. Если вы забудете это сделать, приложение выйдет из строя на более низких версиях.
// You have this check
locationManager.requestWhenInUseAuthorization()
// Add this one
locationManager.requestAlwaysAuthorization()
После попытки ответить на все вышеперечисленные вопросы, если делегат "didUpdateUserLocation" не вызывается, выберите симулятор, нажмите "Отладка", в строке меню выберите "Расположение", затем выберите "Apple". Я пытался прежде всего ответить, но местоположение было настроено как пользовательское, поэтому я изменил его на Apple и вызвал метод делегата. После этого я снова установил его на обычай, теперь он показывает местоположение.
Починил это!
После ios8 MKMapView не загружает LocationCoordinate автоматически。 Если мы хотим использовать MKMapView, чтобы загрузить более точное местоположение с помощью "-mapView:didUpdateUserLocation":
Предпосылка:1. настроить делегата mapView. 2.setShowsUserLocation: ДА 3.mapView должен в контейнере (addSubview:mapView)!!!!!
Пример:
self.mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
_mapView.delegate = self;
[_mapView setShowsUserLocation:YES];
[[UIApplication sharedApplication].keyWindow addSubview:_mapView];
я добавляю MapView в Window, потому что код в UtilSingleton, вы можете добавить к своему виду контроллера вообще.