在 MKMapViewDelegate 中执行代码之前设置一个计时器
Set a timer before executing code in MKMapViewDelegate
使用 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() 将在您提供的时间间隔
后被调用
为 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)
}
}
使用 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() 将在您提供的时间间隔
后被调用为 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)
}
}