Location not updating before the view loads

元气小坏坏 提交于 2019-12-12 04:52:49

问题


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:

  1. 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)
  2. 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
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!