Like this: https://developers.arcgis.com/net/10-2/sample-code/SmoothGraphicAnimation/, but for iOS.
Valentin,
Thank you for your question! While we don't have a specific method for moving a marker/graphic, it is something that can be accomplished using an AGSGraphicsOverlay and an NSTimer. Essentially, when you want to animate a graphic, you create a repeating Timer. When the timer fires, you can update the geometry of the graphic.
Below is a simple view controller (written in Swift 3) that displays a map view with a map and a single graphic. When you tap on the screen, the graphic will start animating toward the tapped point. When it reaches the taped point, it will stop. However, if you tap again before the animation finished, the graphic will start animating towards the new tapped point.
//
// AnimatingGraphicViewController.swift
//
// Created by Mark Dostal on 1/25/17.
//
//
import UIKit
class AnimatingGraphicViewController: UIViewController, AGSGeoViewTouchDelegate {
var mapView : AGSMapView = AGSMapView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
var graphic = AGSGraphic()
var moveToPoint:AGSPoint?
var timer = Timer()
var dx:Double = 0.0
var dy:Double = 0.0
let fireCountMax:Int = 20 //the maximum number of times we want the timer to fire
var fireCount:Int = 0
let timerDuration:Double = 2 //duration in seconds for the animation
override func viewDidLoad() {
super.viewDidLoad()
// add map view
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.frame = view.bounds
view.addSubview(mapView)
//set the mapView's touchDelegate so we get touch events
mapView.touchDelegate = self
//create the map
let map = AGSMap(basemap: AGSBasemap.darkGrayCanvasVector())
mapView.map = map
map.load{ error in
//check for map load error and display if necessary
if let error = error{
let alert = UIAlertController(title: "Error Loading Map", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
else {
//create graphics overlay
let animationGraphicsOverlay = AGSGraphicsOverlay()
//create point geometry and graphic and add the graphic to our animationGraphicsOverlay
let point = AGSPoint(x: 0, y: 0, spatialReference: map.spatialReference)
self.graphic = AGSGraphic(geometry: point, symbol: AGSSimpleMarkerSymbol(style: .circle, color: UIColor.red, size: 24), attributes: nil)
animationGraphicsOverlay.graphics.add(self.graphic)
//add our overlay to the map and make it visible
self.mapView.graphicsOverlays.add(animationGraphicsOverlay)
animationGraphicsOverlay.isVisible = true
}
}
}
func geoView(_ geoView: AGSGeoView, didTapAtScreenPoint screenPoint: CGPoint, mapPoint: AGSPoint) {
//get the current point from the graphic and calculate how far we want it
//to move in each direction
if let currentPoint = graphic.geometry as? AGSPoint {
dx = (mapPoint.x - currentPoint.x) / Double(fireCountMax)
dy = (mapPoint.y - currentPoint.y) / Double(fireCountMax)
}
//set our moveTo point:
moveToPoint = mapPoint
//stop the old timer and remove it from the run loop
timer.invalidate()
//reset the fire count and create and start a new timer
fireCount = 0
timer = Timer.scheduledTimer(timeInterval: timerDuration / Double(fireCountMax),
target:self,
selector: #selector(moveGraphic),
userInfo: nil,
repeats: true)
}
func moveGraphic(_ timer: Timer) {
if fireCount < fireCountMax {
//calculate the new geometry and set it on the graphic
if let currentPoint = graphic.geometry as? AGSPoint {
self.graphic.geometry = AGSPoint(x: currentPoint.x + dx, y: currentPoint.y + dy, spatialReference: currentPoint.spatialReference)
}
fireCount = fireCount + 1
}
else {
//timer reach the fireCount, move to final location (moveToPoint)
//to make sure we're at the correct spot
self.graphic.geometry = moveToPoint
timer.invalidate()
}
}
}