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