如何从自定义位置管理器调用另一个viewcontroller类中的didUpdateLocation?

时间:2018-12-13 21:42:07

标签: swift xcode

我有以下自定义位置管理器类,还有另一个具有地图视图的视图控制器,当用户移动时,如何使用此位置管理器更新地图视图的坐标?由于某些原因,我什至无法在其他视图控制器中调用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)")
        }
    }
}

1 个答案:

答案 0 :(得分:2)

有多种方法可以实现它。

委派:

一个简单方便的方法是创建您的 own 委托!

所以您可以做的是:

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])并使用selfunwarappedSelf)的未包装版本。