E-R*_*die 5 ios sdwebimage google-maps-sdk-ios
将图标设置为GMSMarkerin Google Maps SDK需要UIImage,但目前我的要求是从特定的下载URL
问题是,某种程度上只会显示最后一项.这是关于我如何创建标记的代码(在Swift中更新)
func createMarkers() {
mapView.clear()
let mapCoordinates: [CLLocationCoordinate2D] = coordinates()
let iconURLs: [URL] = imageURLs()
var marker = GMSMarker()
for i in 0..<mapCoordinates.count {
let imageURL = iconURLs[i]
marker = GMSMarker()
marker.position = mapCoordinates[i]
marker.map = mapView
downloadImage(from: imageURL) { image in
marker.icon = image
}
}
}
// It is a helper function calling `SDWebImage` which caches the `UIImage` based on its `URL` string
func downloadImage(from url: URL, completion: @escaping (UIImage) -> Void)
Run Code Online (Sandbox Code Playgroud)
从上面提供的代码中,我在第一次加载数据时遇到了问题,因为引脚显示在地图上但没有图像.如果我createMarkers()在一段时间后再次打电话,图标会正确加载.
我不知道为什么会发生这种情况,有什么建议或提示来解决这个问题?
只需使用 SDWebimage,并且使用 .iconView 而不是 .icon
let imageView = UIImageView(image: pinImage)
imageView.sd_setImage(with: URL(string: "https://pbs.twimg.com/profile_images/469017630796296193/R-bEN4UP.png"), placeholderImage: pinImage)
marker.iconView = imageView
Run Code Online (Sandbox Code Playgroud)
好吧,当时我对并发了解不多,看到所有答案并没有真正解决我真正想要的问题。
URL由于从( )下载图像downloadImage(from url: URL, completion: @escaping (UIImage) -> Void)是后台操作,因此在下载图像时,marker通过在循环中再次初始化,图像已超出范围。
这样就无法知道哪个图像被绑定到哪个标记。
还关于为什么它在重新加载时有效?,SDWebImage重新加载时,已经下载并缓存了图片,所以下次没有延迟,直接绑定到marker。
将可变变量标记作为不可变值在循环内移动。
func createMarkers() {
let mapCoordinates: [CLLocationCoordinate2D] = coordinates()
let iconURLs: [URL] = imageURLs()
for i in 0..<mapCoordinates.count {
let imageURL = iconURLs[i]
let marker = GMSMarker()
marker.position = mapCoordinates[i]
marker.map = mapView
applyImage(from: imageURL, to: marker)
}
}
Run Code Online (Sandbox Code Playgroud)
现在你看到我引入了一个名为 的助手applyImage(from:, to:),它基本上没有做任何特别的事情,只是从 下载图像URL并将其绑定到 type 的参数GMSMarker。
func applyImage(from url: URL, to marker: GMSMarker) {
DispatchQueue.global(qos: .background).async {
guard let data = try? Data(contentsOf: url),
let image = UIImage(data: data)?.cropped()
else { return }
DispatchQueue.main.async {
marker.icon = image
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外还有一个将图像裁剪为44pt X 44pt的扩展,这是不对的,但它只是预览已加载的内容。
extension UIImage {
func cropped() -> UIImage? {
let cropRect = CGRect(x: 0, y: 0, width: 44 * scale, height: 44 * scale)
guard let croppedCGImage = cgImage?.cropping(to: cropRect) else { return nil }
return UIImage(cgImage: croppedCGImage, scale: scale, orientation: imageOrientation)
}
}
Run Code Online (Sandbox Code Playgroud)
注意:整个 ViewController 代码可以在我写的这个Gist 中找到!
| 归档时间: |
|
| 查看次数: |
3880 次 |
| 最近记录: |