初始化后如何从函数中获取值?

Posted

技术标签:

【中文标题】初始化后如何从函数中获取值?【英文标题】:How to get value from function after it has already been initialised? 【发布时间】:2017-09-18 10:30:16 【问题描述】:

我从 Firebase 获取我的坐标,然后将它们放在我的地图上,但问题是我的 Firebase 获取指令发生在地图初始化标记之后,在我的坐标中给出 nil

如何从 Firebase 中获取值并将它们作为标记?

var fetchLat: Double!
var fetchLong: Double!

我在这里从 Firebase 获取值

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

    let camera = GMSCameraPosition.camera(withLatitude: latPass, longitude: longPass, zoom: 5)
    let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    view = mapView
    mapView.settings.scrollGestures = true
    mapView.settings.zoomGestures = true
    mapView.settings.myLocationButton = true

    let dataBaseRef=FIRDatabase.database().reference()
    dataBaseRef.child("LocationTest").queryOrderedByKey().observe(.childAdded, with: (snapshot) in

        let postDict = snapshot.value as? [String : AnyObject] ?? [:]
        var fetchLat = postDict["lat"] as! Double
        var fetchLong = postDict["long"] as! Double
)

我把它们放在地图上

    let friendLocator = [
        Locator(name: "Virat", long: fetchLong, lat: fetchLat),
    ]

    for friend in friendLocator

        let friendMarker = GMSMarker()
        friendMarker.position=CLLocationCoordinate2D(latitude: friend.lat, longitude: friend.long)
        friendMarker.title=friend.name
        friendMarker.map=mapView
        mapView.selectedMarker=friendMarker
    

因为地图初始化是在从 Firebase 获取值之前完成的,所以在获取值之后如何设置标记?

【问题讨论】:

为什么在 didUpdateLocations 中调用 firebase 获取请求。 @Pushpendra 因为我在didUpdateLocations中添加了我的标记 @naveen-saini : view = mapView 那里的视图是什么? Self.view 或单独的 UIView 变量名为 view ?? @SandeepBhandari 只是self.view @naveen-saini :这意味着你的 self.view 是 GMSMapView 类型,那么你不需要在另一个函数中引用 mapView ,你可以简单地说 self.view.selectedMarker=friendMarker 【参考方案1】:

如果在地图上显示用户的 ViewController 与 LocationManager 的代理相同,那么,

在您的 ViewController 中创建一个属性,

var friendLocator : [Locator] = [Locator]()

创建一个在地图上绘制用户的函数

func locateFriends() 
        if self.view is GMSMapView 
            for friend in friendLocator 
                let friendMarker = GMSMarker()
                friendMarker.position=CLLocationCoordinate2D(latitude: friend.lat, longitude: friend.long)
                friendMarker.title=friend.name
                friendMarker.map= (self.view as! GMSMapView)
                (self.view as! GMSMapView).selectedMarker=friendMarker
            
        
    

最后将新找到的定位器实例追加到didUpdateLocationsdelegate中的数组

extension ViewController : UIPageViewControllerDelegate 
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    

        let dataBaseRef=FIRDatabase.database().reference()
        dataBaseRef.child("LocationTest").queryOrderedByKey().observe(.childAdded, with: (snapshot) in

            let postDict = snapshot.value as? [String : AnyObject] ?? [:]
            var fetchLat = postDict["lat"] as! Double
            var fetchLong = postDict["long"] as! Double

            let locator = Locator(name: "Virat", long: fetchLong, lat: fetchLat)
            //do some sort of duplicate check before blindly adding new locator to array
            self.friendLocator.append(locator)
            self.locateFriends()
        )
    

如果在地图上显示用户的 ViewController 不同,则 UILocationManager 委托使用相同的逻辑,但使用delegate 模式通知 ViewController 新的定位器对象并重新加载地图。

编辑:

重新格式化 OP 的代码

import MapKit

import UIKit

import CoreLocation

import GoogleMaps

import GooglePlaces

import GoogleMapsCore

import Firebase

import FirebaseDatabase


struct postStruct

    let lat: Double!

    let long: Double!




class ViewController: UIViewController,MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate


    var viratPin=CustomPointAnnotation()

    var posts=[postStruct]()
    var mapView : GMSMapView? = nil


    var friendLocator : [Locator] = [Locator]()



    @IBOutlet weak var searchBar: UISearchBar!

    @IBOutlet weak var searchSupporter: UIView!

    @IBAction func dismissKeyboard(_ sender: Any) 

        searchBar.resignFirstResponder()

    



    struct Locator 

        let name: String

        let long: CLLocationDegrees

        let lat: CLLocationDegrees

    



    class CustomPointAnnotation: MKPointAnnotation 

        var imageName: String!

    



    let manager = CLLocationManager()

    var myLocation: CLLocationCoordinate2D?

    var friend1: CLLocationCoordinate2D?

    var arbokPin = CustomPointAnnotation()

    var location=0

    var latPass: Double!

    var longPass: Double!

    var fetchLat: Double!

    var fetchLong: Double!



    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

    

        var location=locations[0]

        let span:MKCoordinateSpan=MKCoordinateSpanMake(0.01, 0.01)

        var myLocation:CLLocationCoordinate2D=CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)

        let region:MKCoordinateRegion=MKCoordinateRegionMake(myLocation, span)

        latPass=location.coordinate.latitude

        longPass=location.coordinate.longitude


        post()

        self.configureMapView()

        let dataBaseRef=FIRDatabase.database().reference()

        dataBaseRef.child("LocationTest").queryOrderedByKey().observe(.childAdded, with: (snapshot) in



            let postDict = snapshot.value as? [String : AnyObject] ?? [:]

            var fetchLat = postDict["lat"] as! Double

            var fetchLong = postDict["long"] as! Double


            let locator = Locator(name: "You", long: fetchLong, lat: fetchLat)
            self.friendLocator.append(locator)
            self.locateFriend()
        )

        manager.stopUpdatingLocation()

        self.view = mapView
    


    func configureMapView() 
        let camera = GMSCameraPosition.camera(withLatitude: latPass, longitude: longPass, zoom: 5)

        self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)

        view = mapView

        mapView.settings.scrollGestures = true

        mapView.settings.zoomGestures = true

        mapView.settings.myLocationButton = true

        mapView.addSubview(searchBar)

        mapView.addSubview(searchSupporter)

        mapView.bringSubview(toFront: searchBar)


        for gesture in mapView.gestureRecognizers! 

            mapView.removeGestureRecognizer(gesture)

        
    

    func locateFriend() 
        for friend in friendLocator
            let friendMarker = GMSMarker()

            friendMarker.position=CLLocationCoordinate2D(latitude: friend.lat, longitude: friend.long)

            friendMarker.title=friend.name

            friendMarker.map=mapView

            mapView.selectedMarker=friendMarker

            if friend.name=="Virat"

                friendMarker.icon=UIImage(named: "ViratPin.png")

            

            else if friend.name=="Naveen"

                friendMarker.icon=UIImage(named: "naveenPin.png")

            

            else if friend.name=="You"

                friendMarker.icon=UIImage(named: "currentLocation.png")

            

        

        do 

            mapView.mapStyle = try GMSMapStyle(jsonString: kMapStyle)

         catch 

            NSLog("One or more of the map styles failed to load. \(error)")

        
    

    override func viewDidLoad() 

        super.viewDidLoad()



        manager.delegate=self

        manager.desiredAccuracy=kCLLocationAccuracyBest

        manager.requestWhenInUseAuthorization()

        manager.startUpdatingLocation()

        searchBar.isUserInteractionEnabled=true

        searchBar.delegate=self

        searchSupporter.alpha=0



    





    func searchBarTextDidBeginEditing(_ searchBar : UISearchBar)

        self.searchSupporter.alpha=0.8

        print("yes")

    



    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 

        searchSupporter.alpha=0

        print("no")

    



    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 

        print(searchBar.text!)


    


    override var prefersStatusBarHidden: Bool

        return true

    

    func post()

        let post : [String: Double]=["lat":latPass, "long":longPass]

        let dataBaseRef=FIRDatabase.database().reference()

        //dataBaseRef.child("Location").childByAutoId().setValue(post)

        dataBaseRef.child("Location").child("id").setValue(post)


    

【讨论】:

我的mapView 是在didUpdateLocations 中初始化的,所以我不能在另一个函数中使用它。 @naveen-saini : 我在 didUpdateLocations 中没有看到任何地图初始化代码 @naveen-saini :如果它在 didUpdateLocations 中初始化,您可以为 map 创建一个可选变量,并使其成为您的 ViewController 的实例属性,并在您的 didUpdateLocations 中将其用作 self.mapView,最后在locateFriends 函数在添加 GMSMarker 之前检查 self.mapView != nil thats all @naveen-saini : 给我一秒钟 @naveen-saini : 立即查看

以上是关于初始化后如何从函数中获取值?的主要内容,如果未能解决你的问题,请参考以下文章

JS如何获取值

如何在Elisp中获取变量的初始值?

类的属性

Kotlin集合操作 ⑤ ( Map 集合 | 获取 Map 值 | Map 遍历 | 可变 Map 集合 )

Kotlin集合操作 ⑤ ( Map 集合 | 获取 Map 值 | Map 遍历 | 可变 Map 集合 )

如何从表单组中禁用的表单控件中获取值?