3

I am trying to implement an MKCircle that either increases or decreases in radius as a slider is changed. The issue I have is that when the circle is redrawn it isn't smooth at all. I have read a few other posts and they seem to indicate that you have to create a subclass of MKCircle and somehow do it in that but whenever I look at example code I have a tough time following since its usually not in Swift 3. Could someone show me how to do this? Here is my code for when the slider is changed:

func sliderValueChanged(_ sender:UISlider!) {
    if (!map.selectedAnnotations.isEmpty) {
        for overlay in map.overlays {
            var temp : MKAnnotation = (map.selectedAnnotations.first)!
            if (overlay.coordinate.latitude == temp.coordinate.latitude && overlay.coordinate.longitude == temp.coordinate.longitude) {
                let newCirc : MKCircle = MKCircle(center: temp.coordinate, radius: CLLocationDistance(Float(sender.value*1000)))
                let region: MKCoordinateRegion = MKCoordinateRegionForMapRect(newCirc.boundingMapRect)
                let r: MKCoordinateRegion = map.region
                if (region.span.latitudeDelta > r.span.latitudeDelta || region.span.longitudeDelta > r.span.longitudeDelta){
                    map.setRegion(region, animated: true)
                }
                map.add(MKCircle(center: temp.coordinate, radius: CLLocationDistance(Float(sender.value*1000))))
                map.remove(overlay)
                break
            }
        }

    }
}

Image of what I have so far

tyler
  • 31
  • 3

2 Answers2

0

I solved it as follow:

let currentLocPin = MKPointAnnotation()
var circle:MKCircle!

    func sliderValueDidChange(sender: UISlider) {

            map.remove(circle)

            circle = MKCircle(center: currentLocPin.coordinate, radius: CLLocationDistance(sender.value))
            map.add(circle)
    }

I hope this will help.

Mariam
  • 683
  • 1
  • 11
  • 27
0

I found that updating the circle size on every slider value change was not smooth. I added a check to update the radius only if the slider value has changed by more than 5. This greatly reduces the number of updates required which considerably improves the smoothness of the animation.

var radius: Float = 0.0

@objc private func handleSliderMove() {
    guard let current = mapView.overlays.first else { return }

    let newRadius = CLLocationDistance(exactly: radiusSlider.value) ?? 0.0
    let currentRadius = CLLocationDistance(exactly: self.radius) ?? 0.0

    var diff = (newRadius - currentRadius)
    diff = diff > 0 ? diff : (diff * -1.0)

    if diff > 5 {
        self.mapView.addOverlay(MKCircle(center: current.coordinate, radius: newRadius))
        
        self.mapView.removeOverlay(current)
        self.radius = radiusSlider.value
    }
}
David B.
  • 413
  • 4
  • 6