0

我正在使用 Swift 4 和 Xcode 9.3.1。我包括代码的屏幕截图。

一般来说,我是移动开发/编程的新手,并且一直在考虑如何表达这一点。所以这是我能解释的最好的:

我正在构建一个获取用户位置的应用程序,以便向他们发送帮助。该应用程序获取用户的坐标,并显示一个带有地址信息的 TextView。所以非常直接的 mapKit/coreLocation 功能。到目前为止,一切都很好:使用 startUpdatingLocation() 获取坐标工作正常,我使用 Reverse Geocoder 获取街道名称和位置。但是它们——意味着解码的街道和位置字符串——只有当我在闭包内调用它们时才会打印出来,而不是在它之外。我已经理解(正确还是错误?)需要在类中的多个函数可用的变量应该在顶部全局声明。但是我不知道如何从这个闭包中提取信息以便在其他地方使用它。

我一直在谷歌搜索和阅读 stackOverflow 中的问题,我觉得缺少一些非常简单的东西,但不知道是什么。到目前为止我尝试过的事情都没有成功:

1_在类的开头将全局变量定义为空字符串,并在发生地理编码反向方法的闭包内使用变量名,以尝试存储结果字符串,但是当我尝试在闭包外部打印变量时,全局变量仍然是空字符串 ("")。

[在顶部声明的全局变量][1]

2_定义一个空的全局字符串数组,并将闭包内部的信息附加到全局数组。在闭包之外仍然有一个空数组。(与 1 相同)

3_创建一个函数--func decodedString()--将数据作为字符串 返回,所以我可以通过声明来使用它

*let streetLocation : String = decodedString()*

但是,当我这样声明该函数时:

var street = ""
var locality = ""

// Get the street address from the coordinates
    func deocodedString() -> String {
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location) { placemarks, error in
        if let placemark = placemarks?.first {
        self.street = placemark.name!
        self.locality = placemark.locality!
        let string = "\(self.street), \(self.locality)"
        return string
        }
    }
}

我收到以下错误: void 函数中出现意外的非 void 返回值

在 void 函数中意外没有 void 返回值

最后,如果我使用下面的代码将信息直接传递到闭包内的 TextView 中,我的 textView 会成功更新——但我无法格式化字符串,我需要这样做以使它们看起来像设计说明我正在关注(也就是一些粗体文本、一些常规文本和一些不同大小的文本):

CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
    if let placemark = placemarks?.first {
        self.street = placemark.name!
        self.locality = placemark.locality!
        let string = "\(self.street), \(self.locality)"
        self.addressTextView.text = string
    }
}

所以这就是为什么我不能用 textView.text = string 方法通过它。

我会很感激一些帮助......我一直在寻找 StackOverFlow、youtube 和其他教程的地方,但我无法弄清楚我缺少什么,或者为什么我的函数声明会产生错误。在过去的 24 小时内,我已经多次破坏和反转了我的代码,但没有获得一个独立的字符串,我可以在将其传递到 textView 之前对其应用格式设置,我不知道如何处理它。

4

2 回答 2

0

当您调用此函数时,reverseGeocodeLocation 在后台线程中运行。所以如果你想在这个方法中返回地址,你应该使用转义闭包

    func getaddress(_ position:CLLocationCoordinate2D,completion:@escaping (String)->()) {
     let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location) { placemarks, error in
        if let placemark = placemarks?.first {
        let street = placemark.name!
        let locality = placemark.locality!
        let string = "\(street), \(locality)"
        completion(string)
        }
    } 
    }

   self.getaddress(position.target) { address in
        print(address)
        self.addressTextView.text = address    
   }
于 2018-05-29T02:18:40.640 回答
0

我在使用谷歌地理编码器更新地图屏幕上的标签时遇到问题。

所以我这样做了,首先,创建

swift 文件名:GoogleAPI 随心所欲地调用它。

class GoogleAPI {

    static let sharedInstance = GoogleAPI()

    private init() { }

    var addressValue = ""

    public func geocoding(lat: Double, long: Double) {
        Alamofire.request("https://maps.googleapis.com/maps/api/geocode/json?latlng=\(lat),\(long)&key=YOUR_GOOGLE_KEY").responseJSON { (response) in
            if response.result.isSuccess {
                let dataJSON : JSON = JSON(response.result.value!)
                self.geocoding(json: dataJSON)
            } else {
                print("Error \(response.result.error!)")
            }
        }
    }

    fileprivate func geocoding(json: JSON) {
        let json = json["results"]
        let address = json[1]["formatted_address"].stringValue
        addressValue = address
        print("pin address \(addressValue)")
    }
}

这是对 Google 的 API 调用,用于从响应中获取所有内容并解析唯一的街道。

之后,使用图钉、地图等的地图转到您的视图控制器。

设置一个大头针,标记可拖动。[ marker1.isDraggable = true]

然后添加这个函数

mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker)

并像这样从上面添加调用:

func mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker) {
    GoogleAPI.sharedInstance.geocoding(lat: marker.position.latitude, long: marker.position.longitude)
    DispatchQueue.main.async {
        self.txtSearch.text = GoogleAPI.sharedInstance.addressValue
    }
}

txtSearch 是我的搜索文本字段。

是的,我知道,这可以做得更好,但没有时间。这是有效的。

斯威夫特 4.2

于 2019-01-30T01:50:08.423 回答