mapview上有多个NSTimers

时间:2016-06-15 05:27:34

标签: swift2

我做了一些研究,但找不到任何有价值的东西,所以我想我会问这里。

我有一个带有自定义注释的mapview。在标注中,我想显示倒计时器。从api中检索从时间开始的初始倒计时。我想在用户点击标注中的地图注释时显示倒数计时器。

管理倒计时器的最佳方法是什么,考虑每个注释可能有不同的时间?

我意识到在多个计时器运行时会出现性能损失,但在单个视图控制器上的计时器数量是多少?

感谢任何指导。

由于

1 个答案:

答案 0 :(得分:2)

您无需创建多个NSTimer。只需要在后台运行一个提醒所有注释视图来更新剩余时间。

首先是数据模型:

class MyAnnotation: NSObject, MKAnnotation {
    @objc var coordinate: CLLocationCoordinate2D
    @objc var title: String?
    @objc var subtitle: String?
    @objc var expirationDate: NSDate?

    init(coordinate: CLLocationCoordinate2D, title: String?, subtitle: String?, expirationDate: NSDate?) {
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
        self.expirationDate = expirationDate
    }
}

自定义注释视图&视图控制器:

class MyAnnotationView: MKPinAnnotationView {
    static let formatter = { Void -> NSDateComponentsFormatter in
        let tmp = NSDateComponentsFormatter()
        tmp.allowedUnits = [.Minute, .Second]
        return tmp
    }()

    func updateCountDown() {
        guard let annotation = self.annotation as? MyAnnotation,
              let expirationDate = annotation.expirationDate else {
            return
        }

        annotation.subtitle = MyAnnotationView.formatter.stringFromDate(NSDate(), toDate: expirationDate)
        self.annotation = annotation
    }
}

class ViewController: UIViewController, MKMapViewDelegate {
    @IBOutlet weak var mapView: MKMapView!
    var timer: NSTimer!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.mapView.delegate = self
        addAnnotations()

        self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(ViewController.updateRemainingTime), userInfo: nil, repeats: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func addAnnotations() {
        let coordinate1 = CLLocationCoordinate2D(latitude: 37.3316936, longitude: -122.03021910000001)
        let coordinate2 = CLLocationCoordinate2D(latitude: 37.4224187, longitude: -122.0843491)

        let appleHQ = MyAnnotation(coordinate: coordinate1, title: "Apple HQ", subtitle: "hohoho", expirationDate: NSDate(timeIntervalSinceNow: 240) )
        let googleHQ = MyAnnotation(coordinate: coordinate2, title: "Googleplex", subtitle: nil, expirationDate: NSDate(timeIntervalSinceNow: 180))

        self.mapView.addAnnotation(appleHQ)
        self.mapView.addAnnotation(googleHQ)
        self.mapView.centerCoordinate = coordinate1
        self.mapView.region.span = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
    }

    func updateRemainingTime() {
        for annotation in self.mapView.annotations {
            if let view = self.mapView.viewForAnnotation(annotation) as? MyAnnotationView {
                view.updateCountDown()
            }
        }
    }

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("annotationView")

        if annotationView != nil {
            annotationView!.annotation = annotation
        } else {
            annotationView = MyAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
            annotationView!.canShowCallout = true
        }

        return annotationView
    }
}

结果: Count down with MapView's annotation