使用MKMapView,我想抓住用户完成将地图移动到另一个区域,然后在该区域中显示注释的那一刻。
赶紧他完成移动我使用的地图的时刻:
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool){
}
但是,如果用户开始移动摄像机多一点,我会在调用委托内部的代码之前花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之后被调用
为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()
}
}
一种方法是使用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)
}
}