Swift 获取位置然后加载 table
Swift get location THEN load table
所以我想在用户第一次打开应用程序时询问他们的位置,然后加载 table。这是我现在的代码:
class LayoutController: UICollectionViewController, UICollectionViewDataSource,
UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,
APIControllerProtocol, CLLocationManagerDelegate {
@IBOutlet weak var chainTable: UICollectionView!
@IBOutlet weak var navLogo: UIButton!
let locationManager : CLLocationManager = CLLocationManager()
var lat: String = "lat!"
var long: String = "long!"
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().statusBarStyle = .LightContent
navLogo.userInteractionEnabled = false
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
if( CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
var currentLocation = locationManager.location
var longitude = currentLocation.coordinate.longitude
var latitude = currentLocation.coordinate.latitude
long = String(stringInterpolationSegment: longitude)
lat = String(stringInterpolationSegment: latitude)
}
// Do any additional setup after loading the view.
loadTable(lat, longitude, long)
}
func loadTable(latitude: String, longitude: String){
api = APIController(delegate: self)
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
api!.getPosts(latitude, longitude: longitude)
}
}
首次下载和启用位置后数据未正确加载。但是,当您重新启动应用程序时,我确实可以工作。如何让 table 在加载前检查位置是否已给出?谢谢
(我已经尝试在 if CLLocationManager.authorizationstatus()...
块中使用 loadTable 函数,但也无济于事。)
需要监听CLLocationManagerDelegate的委托方法:
locationManager:didUpdateLocations:
在获得成功结果后,设置并重新加载 table 视图的数据。
正如@dimpiax 所暗示的那样,您的做法是错误的。
位置管理器是异步的API。一旦你确定你被授权使用它,你就要求它开始更新你的位置。然后你等待它调用你的委托方法 locationManager:didUpdateLocations:
.
即使那样你还没有完成。通常你得到的第一个位置是旧的,而且非常非常错误。 (这是 GPS 上次激活时读取的位置。)您必须检查该位置的时间戳,如果时间戳超过几秒则忽略它。
但是等等,您仍然没有完成。一旦你放弃了一个可能过时的位置,你需要等到 GPS 稳定下来并开始提供合适的读数。在您请求位置更新后的前 5 秒或更长时间,读数的误差范围通常非常糟糕。您可以通过检查您获得的位置记录上的水平精度 属性 来解决这个问题。该值实际上是一个半径。大数字不好,小数字好。您可能需要水平精度 <= 100 米的读数。
完成后,您就可以重新加载 table 视图了。
多亏了 Duncan 和 this tutorial
我弄明白了
func locationManager(管理器:CLLocationManager!,didUpdateLocations 位置:[AnyObject]!){
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil){
println("Error:" + error.localizedDescription)
}
if placemarks.count > 0 {
let pm = placemarks[0] as! CLPlacemark
if( CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
var currentLocation = self.locationManager.location
var longitude = currentLocation.coordinate.longitude
var latitude = currentLocation.coordinate.latitude
self.long = String(stringInterpolationSegment: longitude)
self.lat = String(stringInterpolationSegment: latitude)
}
self.displayLocationInfo(pm)
self.loadTable(self.lat, longitude: self.long)
}else{
println("error with data")
}
})
我将其添加到 viewDidLoad 的正下方,并将 Auth
块移入其中。
我创建了一个 class 来获取用户的当前位置并 return 它在一个块中。
class NACurrentLocationTrackManager: NSObject,CLLocationManagerDelegate {
var locationManager: CLLocationManager?
private static var privateShared : NACurrentLocationTrackManager?
typealias completionHandler = (_ location: CLLocation?,_ error: String?) -> Void
var completion: completionHandler?
class func shared() -> NACurrentLocationTrackManager {
guard let uwShared = privateShared else {
privateShared = NACurrentLocationTrackManager()
return privateShared!
}
return uwShared
}
class func destroy() {
privateShared = nil
}
func stopLocationManager() {
locationManager?.stopUpdatingLocation()
}
func startMonitoringLocationWithBlock(handler:@escaping (_ location: CLLocation?,_ error: String?) -> Void){
self.completion = handler
if locationManager == nil{
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.requestAlwaysAuthorization()
}
locationManager?.stopUpdatingLocation()
locationManager?.startUpdatingLocation()
}
func restartMonitoringLocation(){
locationManager?.stopUpdatingLocation()
if CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse{
locationManager?.startUpdatingLocation()
}else if CLLocationManager.authorizationStatus() == .denied{
logh("Location service is disable")
NAAppHelper.showLocationPermissionAlert()
locationManager?.requestAlwaysAuthorization()
}else{
locationManager?.requestAlwaysAuthorization()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let location = locations.last
if let handler = completion {
handler(location, nil)
}
stopLocationManager()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let handler = completion {
handler(nil, "")
}
}
}
And to fetch the location, use this code in your viewcontroller:
NACurrentLocationTrackManager.shared().startMonitoringLocationWithBlock { (location, error) in
if error == nil {
print(location)
}
}
所以我想在用户第一次打开应用程序时询问他们的位置,然后加载 table。这是我现在的代码:
class LayoutController: UICollectionViewController, UICollectionViewDataSource,
UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,
APIControllerProtocol, CLLocationManagerDelegate {
@IBOutlet weak var chainTable: UICollectionView!
@IBOutlet weak var navLogo: UIButton!
let locationManager : CLLocationManager = CLLocationManager()
var lat: String = "lat!"
var long: String = "long!"
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().statusBarStyle = .LightContent
navLogo.userInteractionEnabled = false
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
if( CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
var currentLocation = locationManager.location
var longitude = currentLocation.coordinate.longitude
var latitude = currentLocation.coordinate.latitude
long = String(stringInterpolationSegment: longitude)
lat = String(stringInterpolationSegment: latitude)
}
// Do any additional setup after loading the view.
loadTable(lat, longitude, long)
}
func loadTable(latitude: String, longitude: String){
api = APIController(delegate: self)
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
api!.getPosts(latitude, longitude: longitude)
}
}
首次下载和启用位置后数据未正确加载。但是,当您重新启动应用程序时,我确实可以工作。如何让 table 在加载前检查位置是否已给出?谢谢
(我已经尝试在 if CLLocationManager.authorizationstatus()...
块中使用 loadTable 函数,但也无济于事。)
需要监听CLLocationManagerDelegate的委托方法:
locationManager:didUpdateLocations:
在获得成功结果后,设置并重新加载 table 视图的数据。
正如@dimpiax 所暗示的那样,您的做法是错误的。
位置管理器是异步的API。一旦你确定你被授权使用它,你就要求它开始更新你的位置。然后你等待它调用你的委托方法 locationManager:didUpdateLocations:
.
即使那样你还没有完成。通常你得到的第一个位置是旧的,而且非常非常错误。 (这是 GPS 上次激活时读取的位置。)您必须检查该位置的时间戳,如果时间戳超过几秒则忽略它。
但是等等,您仍然没有完成。一旦你放弃了一个可能过时的位置,你需要等到 GPS 稳定下来并开始提供合适的读数。在您请求位置更新后的前 5 秒或更长时间,读数的误差范围通常非常糟糕。您可以通过检查您获得的位置记录上的水平精度 属性 来解决这个问题。该值实际上是一个半径。大数字不好,小数字好。您可能需要水平精度 <= 100 米的读数。
完成后,您就可以重新加载 table 视图了。
多亏了 Duncan 和 this tutorial
我弄明白了func locationManager(管理器:CLLocationManager!,didUpdateLocations 位置:[AnyObject]!){
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil){
println("Error:" + error.localizedDescription)
}
if placemarks.count > 0 {
let pm = placemarks[0] as! CLPlacemark
if( CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
var currentLocation = self.locationManager.location
var longitude = currentLocation.coordinate.longitude
var latitude = currentLocation.coordinate.latitude
self.long = String(stringInterpolationSegment: longitude)
self.lat = String(stringInterpolationSegment: latitude)
}
self.displayLocationInfo(pm)
self.loadTable(self.lat, longitude: self.long)
}else{
println("error with data")
}
})
我将其添加到 viewDidLoad 的正下方,并将 Auth
块移入其中。
我创建了一个 class 来获取用户的当前位置并 return 它在一个块中。
class NACurrentLocationTrackManager: NSObject,CLLocationManagerDelegate {
var locationManager: CLLocationManager?
private static var privateShared : NACurrentLocationTrackManager?
typealias completionHandler = (_ location: CLLocation?,_ error: String?) -> Void
var completion: completionHandler?
class func shared() -> NACurrentLocationTrackManager {
guard let uwShared = privateShared else {
privateShared = NACurrentLocationTrackManager()
return privateShared!
}
return uwShared
}
class func destroy() {
privateShared = nil
}
func stopLocationManager() {
locationManager?.stopUpdatingLocation()
}
func startMonitoringLocationWithBlock(handler:@escaping (_ location: CLLocation?,_ error: String?) -> Void){
self.completion = handler
if locationManager == nil{
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.requestAlwaysAuthorization()
}
locationManager?.stopUpdatingLocation()
locationManager?.startUpdatingLocation()
}
func restartMonitoringLocation(){
locationManager?.stopUpdatingLocation()
if CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse{
locationManager?.startUpdatingLocation()
}else if CLLocationManager.authorizationStatus() == .denied{
logh("Location service is disable")
NAAppHelper.showLocationPermissionAlert()
locationManager?.requestAlwaysAuthorization()
}else{
locationManager?.requestAlwaysAuthorization()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let location = locations.last
if let handler = completion {
handler(location, nil)
}
stopLocationManager()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let handler = completion {
handler(nil, "")
}
}
}
And to fetch the location, use this code in your viewcontroller:
NACurrentLocationTrackManager.shared().startMonitoringLocationWithBlock { (location, error) in
if error == nil {
print(location)
}
}