我有以下自定义位置管理器类,我有另一个具有地图视图的视图控制器,当用户移动时,我如何使用此位置管理器更新地图视图的坐标?由于某些原因,我甚至无法调用另一个视图控制器中的didUpdateLocations
函数。
class CustomLocationManager:NSObject, CLLocationManagerDelegate {
static let shared = CustomLocationManager()
var locationManager = CLLocationManager()
private override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func startTracking() {
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
}
func stopTracking(){
locationManager.stopUpdatingHeading()
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for currentLocation in locations{
print("(index):(currentLocation)")
}
}
}
实现它的方法不止一种。
代表团:
一个简单方便的方法是创建自己的代理!
所以你可以做的是:
protocol CustomLocationManagerDelegate: class {
func customLocationManager(didUpdate locations: [CLLocation])
}
class CustomLocationManager:NSObject, CLLocationManagerDelegate {
static let shared = CustomLocationManager()
// tip: it is better to declare `locationManager` as private, so you can only access it
// from the manager...
private var locationManager = CLLocationManager()
// here is the delegate:
weak var delegate: CustomLocationManagerDelegate?
private override init()
{
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest}
func startTracking()
{
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
}
func stopTracking()
{
locationManager.stopUpdatingHeading()
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// calling the delegate method
delegate?.customLocationManager(didUpdate: locations)
}
}
因此,在视图控制器中使用CustomLocationManager
时,只需确保它符合CustomLocationManagerDelegate
;示例:
class MyViewController: UIViewController {
// ...
override func viewDidLoad() {
super.viewDidLoad()
CustomLocationManager.shared.startTracking()
CustomLocationManager.shared.delegate = self
}
// ...
}
extension MyViewController: CustomLocationManagerDelegate {
func customLocationManager(didUpdate locations: [CLLocation]) {
// here we go:
for currentLocation in locations {
print("(index):(currentLocation)")
}
}
}
关闭:
另一种实现方法是在CustomLocationManager
:中声明闭包
class CustomLocationManager:NSObject, CLLocationManagerDelegate {
static let shared = CustomLocationManager()
// here is the closure
var updatedLocations: (([CLLocation]) -> Void)?
// tip: it is better to declare `locationManager` as private, so you can only access it
// from the manager...
private var locationManager = CLLocationManager()
// here is the delegate:
weak var delegate: CustomLocationManagerDelegate?
private override init()
{
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest}
func startTracking()
{
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
}
func stopTracking()
{
locationManager.stopUpdatingHeading()
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// here we call it:
updatedLocations?(locations)
}
}
因此,在视图控制器中:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
CustomLocationManager.shared.startTracking()
CustomLocationManager.shared.updatedLocations = { [weak self] locations in
guard let unwarappedSelf = self else { return }
// unwarappedSelf.blablabla
for currentLocation in locations {
print(currentLocation)
}
}
}
}
如果您打算采用这种方法,请记住:为了避免保留循环,不要忘记使用weak self
(捕获列表[weak self]
(进行闭包,并使用self
(unwarappedSelf
(的展开版本。