MKMapItem.openInMaps() 50% 的时间准确地显示地点标记
Posted
技术标签:
【中文标题】MKMapItem.openInMaps() 50% 的时间准确地显示地点标记【英文标题】:MKMapItem.openInMaps() displays place mark exactly 50% of the time 【发布时间】:2016-12-28 21:13:36 【问题描述】:我发现运行一些代码以在地图视图 MKMapItem.openInMaps()
中显示位置仅在 50% 的时间内有效。
事实上,它恰好在 MKPlacemark
被显示和不被显示之间交替。
例如,每第 1、3、5、7...n 次代码运行一次,它就会显示地标,但每运行 2、4、6、8...m 次,地标不是显示出来。
运行下面发布的代码,这是 100% 可重现的。 这似乎是一个错误,但如果是这样,我很惊讶它之前没有被报告或修复。但考虑到失败正是在成功和失败之间交替出现,这让我认为还有其他事情发生,因此我在这里发帖看看是否有人熟悉这个问题,或者有什么应该做的事情缺失了从代码中,或者有一个解决方法:
override func viewDidAppear(_ animated: Bool)
displayMap()
func displayMap()
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString("1 Infinite Loop, Cupertino,California") (placemark: [CLPlacemark]?, error: Error?) -> Void in
if error == nil
if let placemark = placemark, placemark.count > 0
let location = placemark.first
let latitude = (location?.location?.coordinate.latitude)!
let longitude = (location?.location?.coordinate.longitude)!
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
let regionDistance:CLLocationDistance = 100000
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Apple"
mapItem.phoneNumber = "(405) 123-4567"
mapItem.openInMaps(launchOptions: options)
else
assert(false, "Unable to geocode")
这是代码运行第一次、第三次、第五次、第七次...时的结果
这是代码运行第二、四、六、八……次时的结果
注意失败截图中不仅地图上不显示地标,而且上滑也是空的。
(目前在 10.2 上观察到这一点,但在其他版本上也看到过)
【问题讨论】:
好的,所以我尝试了您的代码,问题在于,一旦您将位置居中并显示,如果您不关闭它并再次启动应用程序,它将不会显示它。因此,当您启动它并显示信息时,通过按 x 关闭 Map 应用程序内的弹出窗口并再次运行它,它将起作用......话虽如此,我不太确定究竟是什么导致了问题或如何摆脱它。 我注意到的另一件事是,如果地图应用程序中有任何其他先前的通知或位置放大,它仍然不会显示您的启动选项。我在应用程序中单击了我的位置,它显示了一个弹出窗口,我再次重新启动了应用程序,但它无法显示选项。所以,我认为这是一个错误。 @return0 感谢您的意见 【参考方案1】:免责声明
是的,似乎mapItem.openInMaps
中存在一个错误,它将行车路线作为叠加层打开。
正如@return0准确描述的那样:
...我尝试了您的代码,问题在于,一旦您将位置居中并显示,如果您不关闭它并再次启动应用程序,它将不会显示...
更多奇事
-
第二次,
mapItem.openInMaps
确实关闭行车路线叠加层(而不是显示新位置)
如果用户关闭所述叠加层,地图不再混乱(*)
(*) 这种情况的另一个奇怪之处在于,一旦覆盖层关闭,该位置就会消失。
错误? → 解决方法!
通过请求多个位置来强制路线覆盖消失。在实践中,这意味着调用两次相同位置的地图:
MKMapItem.openMaps(with: [mapItem, mapItem], launchOptions: options)
解决方法奖励
即使用户点击锚点并请求行驶方向,随后从您的应用程序调用地图到该位置或其他位置不会让它挂起。换句话说,它按预期工作。
完整的 Swift 3 源代码
func displayMap(_ address:String, name:String, tph:String)
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) (placemark: [CLPlacemark]?, error: Error?) -> Void in
assert(nil == error, "Unable to geocode \(error)")
if error == nil
if let placemark = placemark, placemark.count > 0
let location = placemark.first
let latitude = (location?.location?.coordinate.latitude)!
let longitude = (location?.location?.coordinate.longitude)!
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
let regionDistance:CLLocationDistance = 10000
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = name
mapItem.phoneNumber = tph
MKMapItem.openMaps(with: [mapItem, mapItem], launchOptions: options)
else
print("Something wrong with \(placemark)")
...和调用
@IBAction func doApple()
displayMap("1 Infinite Loop, Cupertino, California", name: "Apple", tph: "(408) 996–1010")
@IBAction func doMicrosoft()
displayMap("One Microsoft Way, Redmond, WA", name: "Microsoft", tph: "1-800-MICROSOFT")
@IBAction func doIBM()
displayMap("1 New Orchard Road. Armonk, New York", name: "IBM", tph: "(914) 499-1900")
【讨论】:
感谢您的回复 太棒了。你找到你的仓鼠了吗?这是一个相当有趣的难题,我相信当 Apple 修复该重新进入错误时,该解决方案仍然有效。 这似乎已在 ios 10.3 beta 3 中得到修复 干得好 SwiftArchitect(这对我的 obj-c 应用程序也有帮助)。我对 >= 10.0 和 【参考方案2】:在 iOS 10.3.2 上,这个问题对我来说仍然存在。但是,此解决方法使 mapItem
不会消失:
MKMapItem.openMaps(with: [mapItem], launchOptions: options)
【讨论】:
以上是关于MKMapItem.openInMaps() 50% 的时间准确地显示地点标记的主要内容,如果未能解决你的问题,请参考以下文章