问题
I have a variable "zipCode" that I am trying to update to the users current location before the views load in my scrollView. Currently it updates to the correct location once I segue out and back into the the scrollView view controller. Also where I should implement the change for authorization update for a fresh install. Thank you for any help in advanced.
import UIKit
import CoreLocation
var zipCode = 90210
var location = [""]
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
@IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
////Current Location
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: { (placemarks, error)-> Void in
if (error != nil) {
print("Error: + error.localizedDescription")
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
self.displayLocationInfo(pm)
}else {
print("Error with data")
}
})
}
func displayLocationInfo(placemark: CLPlacemark) {
self.locationManager.stopUpdatingLocation()
let zip = placemark.postalCode
if let zip2 = numberFormatter.numberFromString(zip!)?.integerValue {
zipCode = zip2
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error: " + error.localizedDescription)
}
///// Load Views
override func viewWillAppear(animated: Bool) {
let vc0 = self.storyboard?.instantiateViewControllerWithIdentifier("storyBoard0") as UIViewController!
self.addChildViewController(vc0)
self.scrollView.addSubview(vc0.view)
vc0.didMoveToParentViewController(self)
vc0.view.frame = scrollView.bounds
vc0.viewDidLoad()
let vc1 = self.storyboard?.instantiateViewControllerWithIdentifier("storyBoard2") as UIViewController!
self.addChildViewController(vc1)
self.scrollView.addSubview(vc1.view)
vc1.didMoveToParentViewController(self)
vc1.view.frame = scrollView.bounds
var vc1Frame: CGRect = vc1.view.frame
vc1Frame.origin.x = self.view.frame.width
vc1.view.frame = vc1Frame
vc1.viewDidLoad()
let vc2 = self.storyboard?.instantiateViewControllerWithIdentifier("storyBoard1") as UIViewController!
self.addChildViewController(vc2)
self.scrollView.addSubview(vc2.view)
vc2.didMoveToParentViewController(self)
vc2.view.frame = scrollView.bounds
var vc2Frame: CGRect = vc2.view.frame
vc2Frame.origin.x = 2 * self.view.frame.width
vc2.view.frame = vc2Frame
vc2.viewDidLoad()
let vc3 = self.storyboard?.instantiateViewControllerWithIdentifier("storyBoard3") as UIViewController!
self.addChildViewController(vc3)
self.scrollView.addSubview(vc3.view)
vc3.didMoveToParentViewController(self)
vc3.view.frame = scrollView.bounds
var vc3Frame: CGRect = vc3.view.frame
vc3Frame.origin.x = 3 * self.view.frame.width
vc3.view.frame = vc3Frame
vc3.viewDidLoad()
self.scrollView.contentSize = CGSizeMake((self.view.frame.width) * 4, (self.view.frame.height))
}
}
回答1:
What you noticed is due to the fact that CLLocationManager is an asynchronous class, this meaning that there can be a delay between the moment you start it and the moment you receive the location. This delay might not always be big, but in most cases is enough to have didUpdateLocations run after viewDidLoad.
Similarly, if the user has not yet authorized your application for location usage, you'll only obtain the location after the user pressed allow (or you receive a failure if the user doesn't approve it).
A few recommendations:
- be prepared to receive the location after the view got displayed, e.g. display some informative text (or a spinner). Or ask for location as soon as possible and don't move forward to the problematic controller if you didn't yet receive the location (inform the user somehow about this)
- depending on the specifications of your application, you can either request location authorization only when you need it (like in your code), or at startup
- wrap the location manager related code into a custom class of yours, that you can simply ask for it's location, this will make things easier when you'll need to use location in multiple controllers.
There's a very useful article on nshipster.com about CoreLocation, I'd recommend you go through it, it will clarify a lot of aspects about location services in iOS. You can find the article here
来源:https://stackoverflow.com/questions/34585909/location-not-updating-before-the-view-loads