刷新标记而不刷新整个 Google 地图(Swift 2.0,Xcode v 7.0.1)
Refresh markers without refreshing entire Google map (Swift 2.0, Xcode v 7.0.1)
我正在构建一个应用程序,它使用 Swift 2.0 中的 Google Maps SDK 在地图上显示公交车的位置。我有一个 XML 文件,每 10 秒更新一次并显示所有活动航天飞机的纬度和经度。在我的代码中,我有标记对象,这些标记对象具有用于 lats、longs、ID 和总线名称的字段。
我已经放置了显示地图的代码,该代码以我想要显示公交车的位置为中心,以及循环遍历所有公交车位置的 for 循环,以将它们显示在地图上作为名为 [= 的函数中的标记32=]realoadBuses()。在这个函数中,我还有与 XML 文件通信的代码行。
我使用 NSTimer() 每 10 秒调用一次 realoadBuses(),这样公交车的位置就会相应地更新。
以下是我的代码:
// runs reloadBuses() every 10 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "reloadBuses", userInfo: nil, repeats: true)
func reloadBuses() {
// displays the map adjusted on Campus
let camera = GMSCameraPosition.cameraWithLatitude(37.0000,
longitude: -122.0600, zoom: 14)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
// XML file
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://link.to.xml.file.xml"))!)!
let coord = Coord2()
parser.delegate = coord
parser.parse()
print("coord has a count attribute of \(coord.count)")
print("coord has \(coord.markers.count) markers")
// loops through all the lats and lngs of the buses and produces a marker
// for them on our Google Maps app
for marker in coord.markers {
print("marker id=\(marker.id), lat=\(marker.lati), lng=\(marker.lngi), route=\(marker.route)")
// displays the buses
let buses = GMSMarker()
buses.position = CLLocationCoordinate2DMake(marker.lati, marker.lngi)
buses.title = marker.route
if buses.title == "UPPER CAMPUS" {
buses.icon = UIImage(named: "uppercampus")
} else if buses.title == "LOOP" {
buses.icon = UIImage(named: "innerloop")
}
buses.snippet = marker.id
buses.map = mapView
}
}
我遇到的问题是,每次 NSTimer() 调用 reloadBuses() 时,地图和公交车标记都会刷新。
我知道会发生这种情况,因为我有在 reloadBuses() 函数中显示地图的代码。我试图将那段代码放在调用 NSTimer() 之前的某处,但是 mapView 超出了 reloadBuses 内部 for 循环中最后一行所需的范围( ).
然后我尝试通过
将 mapView 传递到 reloadBuses()
// displays the map adjusted on Campus
let camera = GMSCameraPosition.cameraWithLatitude(37.0000,
longitude: -122.0600, zoom: 14)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
// runs reloadBuses() every 10 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "reloadBuses(mapView)", userInfo: nil, repeats: true)
reloadBuses(map: GMSMapView){
...
for loop {
...
buses.map = map
}
并且代码会成功构建并且地图会显示而没有任何标记(公共汽车),但是大约几秒钟后应用程序会崩溃并且我会收到此错误:
**2015-10-28 19:42:05.731 GeoBus[1926:107070] -[GeoBus.ViewController reloadBuses(self.view)]: unrecognized selector sent to instance 0x7f91784aebc0
2015-10-28 19:42:05.743 GeoBus[1926:107070] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GeoBus.ViewController reloadBuses(mapView)]: unrecognized selector sent to instance 0x7f91784aebc0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010600bf65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000107cd9deb objc_exception_throw + 48
2 CoreFoundation 0x000000010601458d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000105f61f7a ___forwarding___ + 970
4 CoreFoundation 0x0000000105f61b28 _CF_forwarding_prep_0 + 120
5 Foundation 0x00000001063f1671 __NSFireTimer + 83
6 CoreFoundation 0x0000000105f6c364 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
7 CoreFoundation 0x0000000105f6bf11 __CFRunLoopDoTimer + 1089
8 CoreFoundation 0x0000000105f2d8b1 __CFRunLoopRun + 1937
9 CoreFoundation 0x0000000105f2ce98 CFRunLoopRunSpecific + 488
10 GraphicsServices 0x0000000109e03ad2 GSEventRunModal + 161
11 UIKit 0x0000000106828676 UIApplicationMain + 171
12 GeoBus 0x0000000103ca7bfd main + 109
13 libdyld.dylib 0x000000010880292d start + 1
14 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException**
是的,每次您调用时都会重新创建地图:
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
我建议您改为在界面生成器中设置地图视图,然后通过 IB 向您的 class 添加出口的能力来绑定它。
至于四处移动标记,您需要做的是在您的代码中保留数据结构中的标记并移动它们,而不是尝试在每次从服务器刷新数据时重新创建显示。
我正在构建一个应用程序,它使用 Swift 2.0 中的 Google Maps SDK 在地图上显示公交车的位置。我有一个 XML 文件,每 10 秒更新一次并显示所有活动航天飞机的纬度和经度。在我的代码中,我有标记对象,这些标记对象具有用于 lats、longs、ID 和总线名称的字段。
我已经放置了显示地图的代码,该代码以我想要显示公交车的位置为中心,以及循环遍历所有公交车位置的 for 循环,以将它们显示在地图上作为名为 [= 的函数中的标记32=]realoadBuses()。在这个函数中,我还有与 XML 文件通信的代码行。
我使用 NSTimer() 每 10 秒调用一次 realoadBuses(),这样公交车的位置就会相应地更新。
以下是我的代码:
// runs reloadBuses() every 10 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "reloadBuses", userInfo: nil, repeats: true)
func reloadBuses() {
// displays the map adjusted on Campus
let camera = GMSCameraPosition.cameraWithLatitude(37.0000,
longitude: -122.0600, zoom: 14)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
// XML file
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://link.to.xml.file.xml"))!)!
let coord = Coord2()
parser.delegate = coord
parser.parse()
print("coord has a count attribute of \(coord.count)")
print("coord has \(coord.markers.count) markers")
// loops through all the lats and lngs of the buses and produces a marker
// for them on our Google Maps app
for marker in coord.markers {
print("marker id=\(marker.id), lat=\(marker.lati), lng=\(marker.lngi), route=\(marker.route)")
// displays the buses
let buses = GMSMarker()
buses.position = CLLocationCoordinate2DMake(marker.lati, marker.lngi)
buses.title = marker.route
if buses.title == "UPPER CAMPUS" {
buses.icon = UIImage(named: "uppercampus")
} else if buses.title == "LOOP" {
buses.icon = UIImage(named: "innerloop")
}
buses.snippet = marker.id
buses.map = mapView
}
}
我遇到的问题是,每次 NSTimer() 调用 reloadBuses() 时,地图和公交车标记都会刷新。
我知道会发生这种情况,因为我有在 reloadBuses() 函数中显示地图的代码。我试图将那段代码放在调用 NSTimer() 之前的某处,但是 mapView 超出了 reloadBuses 内部 for 循环中最后一行所需的范围( ).
然后我尝试通过
将 mapView 传递到 reloadBuses()// displays the map adjusted on Campus
let camera = GMSCameraPosition.cameraWithLatitude(37.0000,
longitude: -122.0600, zoom: 14)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
// runs reloadBuses() every 10 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "reloadBuses(mapView)", userInfo: nil, repeats: true)
reloadBuses(map: GMSMapView){
...
for loop {
...
buses.map = map
}
并且代码会成功构建并且地图会显示而没有任何标记(公共汽车),但是大约几秒钟后应用程序会崩溃并且我会收到此错误:
**2015-10-28 19:42:05.731 GeoBus[1926:107070] -[GeoBus.ViewController reloadBuses(self.view)]: unrecognized selector sent to instance 0x7f91784aebc0 2015-10-28 19:42:05.743 GeoBus[1926:107070] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GeoBus.ViewController reloadBuses(mapView)]: unrecognized selector sent to instance 0x7f91784aebc0' *** First throw call stack: ( 0 CoreFoundation 0x000000010600bf65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000107cd9deb objc_exception_throw + 48 2 CoreFoundation 0x000000010601458d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x0000000105f61f7a ___forwarding___ + 970 4 CoreFoundation 0x0000000105f61b28 _CF_forwarding_prep_0 + 120 5 Foundation 0x00000001063f1671 __NSFireTimer + 83 6 CoreFoundation 0x0000000105f6c364 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 7 CoreFoundation 0x0000000105f6bf11 __CFRunLoopDoTimer + 1089 8 CoreFoundation 0x0000000105f2d8b1 __CFRunLoopRun + 1937 9 CoreFoundation 0x0000000105f2ce98 CFRunLoopRunSpecific + 488 10 GraphicsServices 0x0000000109e03ad2 GSEventRunModal + 161 11 UIKit 0x0000000106828676 UIApplicationMain + 171 12 GeoBus 0x0000000103ca7bfd main + 109 13 libdyld.dylib 0x000000010880292d start + 1 14 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException**
是的,每次您调用时都会重新创建地图:
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.mapType = kGMSTypeNormal
mapView.myLocationEnabled = true
self.view = mapView
我建议您改为在界面生成器中设置地图视图,然后通过 IB 向您的 class 添加出口的能力来绑定它。
至于四处移动标记,您需要做的是在您的代码中保留数据结构中的标记并移动它们,而不是尝试在每次从服务器刷新数据时重新创建显示。