Установите таймер перед выполнением кода в MKMapViewDelegate - PullRequest
1 голос
/ 06 марта 2020

Используя MKMapView, я хочу поймать момент, когда пользователь закончил перемещать карту в другой регион, чтобы затем отобразить аннотации в этой области.

Чтобы поймать момент, когда он закончил, чтобы переместить карту, которую я использую :

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

Однако я бы порекомендовал добавить промежуток времени в 1 с до вызова кода внутри делегата на случай, если пользователь начнет немного больше двигать камеру. И если пользователь снова перемещает карту до истечения этого промежутка времени, он, конечно, отменяет выполнение кода.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 06 марта 2020

Создайте свойство для 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()
    }
}
1 голос
/ 06 марта 2020

Один из способов сделать это - использовать 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)
    }
}
1 голос
/ 06 марта 2020

Объявите таймер:

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 () будет вызван после указанного вами времениInterval

...