在MKMapViewDelegate中执行代码之前设置计时器

问题描述 投票:0回答:3

使用MKMapView,我想抓住用户完成将地图移动到另一个区域,然后在该区域中显示注释的那一刻。

赶紧他完成移动我使用的地图的时刻:

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool){
}

但是,如果用户开始移动摄像机多一点,我会在调用委托内部的代码之前花1秒的时间间隔。而且,如果用户在此时间间隔结束之前再次移动地图,那么它当然会取消代码的执行。

任何想法?

ios swift delegates mapkit mkmapview
3个回答
1
投票

声明一个计时器:

var delayTimer:Timer? = nil

然后编写这些方法:

private func stopDelayTimer(){
    self.delayTimer?.invalidate()
    self.delayTimer = nil
}

private func startDelayTimer(timeIntervalInSecond : Int){
    self.stopDelayTimer()

    delayTimer = Timer.scheduledTimer(timeInterval:TimeInterval(timeIntervalInSecond),target:self,selector:#selector(onDelayTimeOut), userInfo: nil, repeats: false)
}

@objc fileprivate func onDelayTimeOut(){
        //do Your  work here
}

从您的委托方法开始通话:

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool){
self.startDelayTimer(timeIntervalInSecond: 1)
}

onDelayTimeOut()将在您提供的timeInterval之后被调用


0
投票

URLSessionDataTask类型创建属性并在地图视图委托方法中调用cancel方法

class ViewController: UIViewController {

    var task: URLSessionDataTask?

    func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool){
        task?.cancel()
        perform(#selector(fetchDetails), with: self, afterDelay: 1.0)
    }

    @objc func fetchDetails() {

        let request = URLRequest(url: URL(string: "yourURL")!)
        task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in

        })
        task?.resume()
    }
}

0
投票

一种方法是使用DispatchWorkItem,该对象封装一些代码以供以后执行。当用户再次使用mapView(_:regionWillChangeAnimated:)方法开始移动地图视图时,您可以取消工作项:

class YourClass: NSObject, MKMapViewDelegate {
    private var userFinishedMovingMapViewWorkItem: DispatchWorkItem?

    func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
        // Cancel any previous work item
        userFinishedMovingMapViewWorkItem?.cancel()
    }

    func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
        // Create a new work item, store it in a property, and set it to execute
        // on the main queue after one second from now
        let workItem = DispatchWorkItem(qos: .userInteractive) {
            // Code you want to execute after 1 second
        }

        userFinishedMovingMapViewWorkItem = workItem
        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: workItem)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.