我有一个带有移动注解的mapView。假设它显示了一辆汽车沿着道路行驶。用户可以将他们的运输方式从汽车更改为摩托车。我无法使注释从汽车图像(CarAnnotation类型)平稳过渡到自行车注释(BikeAnnotation)。我已经尝试了在didUpdateLocations方法中链接动画的各种方法,但是通常发生的是旧的(汽车)注释会很快消失,而新的(自行车)注释会花费几秒钟的时间出现,并且似乎会以轻微的随机偏移进行动画处理方向(不是从刚刚删除的旧批注的位置开始)。我该如何优雅地制作动画?
/// Main locmanager delegate method. sent when USER moves according to vars in loc man setup ie .best & 10m
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// -----------------------
// Checks and setup
// check user
guard let uid = uid else { return }
// check location not nil
guard let userLocation = locations.last else { return }
// check accuracy. if first run (userLoc=nil) let code continue
let accuracy = userLocation.horizontalAccuracy
if self.userLocation != nil && (accuracy < 0 || accuracy > reqAccuracy) {
return // wait for next didUpdateLoc call
}
// set userlocation prop
self.userLocation = userLocation
//TODO: should allow user to scroll map to look at different area, with button & timer to return
// should have button to allow to return to current location or automatically return
// switch to indicate user is zooming, panning needed. should only set region if the user has not panned away
// set map region
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegionMake(userLocation.coordinate, span)
mapView.setRegion(region, animated: true)
// -----------------------
// Create annotations
// check mode
guard let mode = self.transportMode else { return } // ider transport mode
// create new or reused ann
let ann = Annotation.createOrUpdateAnnotation(uid: uid, user: .ider(mode: mode), userLocation: userLocation, prevAnn: annotations[uid])
// set status (for tint). also done in idReq status var observer
if let annStatusString = self.idRequest?.latestStatus?.desc() {
let annStatus = _IDRequestStatus.init(rawValue: annStatusString)
ann.requestStatus = annStatus
}
// check if ann type (transport mode proxy) has changed from prev ann
if let prevAnn = annotations[uid], !ann.isEqual(prevAnn) {
// add new ann to map
// animate removal of prev ann view
let prevAnnView = mapView.view(for: prevAnn)
UIView.animate(withDuration: 0.4, animations: {
prevAnnView?.alpha = 0
self.mapView.addAnnotation(ann)
}) { (finished) in
self.mapView.removeAnnotation(prevAnn)
prevAnnView?.alpha = 1.0 //reset alpha for view reuse
}
} else {
// same ann type (transport mode proxy)
// add to map
mapView.addAnnotation(ann)
// animate to new location
UIView.animate(withDuration: 0.4) {
ann.annLocation = userLocation // update the cllocation of the userAnn to trigger movement
}
}
// -----------------------
// save ann
// save to dic
self.annotations[uid] = ann
// save to database
saveIderLocationToGeoFirestore()
} // didUpdateLocation