我正在学习Ray Wenderlich的site的MapKit教程,我对几行代码所说的有点困惑。
特别是在注释//4下,开发人员似乎使用了一个常量变量,该变量等于mappview的函数,然后将其强制转换为MKMarkAnnotationView类型。
我从未见过这样的事,但我想在继续之前先了解一下。我知道函数也是对象,我知道可以将函数放在变量中,但是在本例中,开发人员不仅将函数放在变量中,而且还将其强制转换为另一种类型,这是令人困惑的。这行代码可以分解成更小的步骤来帮助我更好地理解它吗?
开发人员似乎调用了mkmappview类型的mappview对象,但可以选择将其强制转换为MKMarkerAnnotationView类型。
//4
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
}
以下是viewController的完整代码(如果需要):
import UIKit
import MapKit
class ViewController: UIViewController {
//created an IBOutlet to control the mapView in interface builder
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//initial location to zoom the map into once the app is opened.
let initialLocation = CLLocation.init(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(location: initialLocation)
mapView.delegate = self
let artwork = Artwork.init(title: "King David Kalakaua", locationName: "Waikiki Gateway Park", discipline: "Sculpture", coordinate: CLLocationCoordinate2D.init(latitude: 21.283921, longitude: -157.831661))
mapView.addAnnotation(artwork)
}
//when specifying a latlong to zoom into in iOS, you must also state a rectangular region for it to display a correct zoom level???
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation){
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius, regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//2
guard let annotation = annotation as? Artwork else {
return nil
}
//3
let identifier = "marker"
var view: MKMarkerAnnotationView
//4
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
//5
view = MKMarkerAnnotationView.init(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint.init(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton.init(type: .detailDisclosure)
view.markerTintColor = UIColor.green
}
return view
}
}
最佳答案
这是可选的展开。
正如您所注意到的-developer可以选择将函数的结果强制转换为MKMarkerAnnotationView
。但他也使用了if let
语法,这是可选的展开。这意味着这个代码
dequeuedView.annotation = annotation
view = dequeuedView
仅当强制转换成功(即,如果强制转换结果不是
nil
)时才会执行。否则将忽略此代码。您也可以使用
guard
语句来执行此操作。例如。:guard let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView
else { // code here will be executed if casting fails. In this case you also have to return function }
dequeuedView.annotation = annotation
view = dequeuedView
更多信息in documentation
关于swift - 在Swift中,可以将另一个对象的函数强制转换为其他类型的对象吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48855928/