首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SwiftUI中以km显示两个坐标之间的距离

在SwiftUI中以km显示两个坐标之间的距离
EN

Stack Overflow用户
提问于 2022-09-15 18:12:25
回答 1查看 98关注 0票数 0

在我的项目中,我获取有关房屋/建筑物的数据,以及其他细节,我展示了它离用户有多远。我只是一个初学者,所以我会尽量明确。

我的问题是,我不知道将计算公里距离的函数放在哪里,以及如何在MVVM项目中正确调用它。请注意,我有一个ViewModel文件,其中包括负责网络ViewModel类和负责跟踪用户位置的LocationManager类。纬度和经度来自API的ViewModel,我认为距离的计算应该用LocationManager进行。我不知道如何“连接”这两个类。

我的主要目标是:

  • 确定了把漏斗放在哪里来计算距离。用户协和可以从LocationManager访问,而房屋协和可以从API访问。我想知道是否有一种方法可以合并这两个类来使用一个函数中的数据.

  • 理解distanceInKM方法是否正确。尽管它不抛出,但它仍然显示一个占位符值。

作为最小可重复的项目,下面是代码:

ContentView:

代码语言:javascript
复制
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
@StateObject var locationManager = LocationManager()
var body: some View {
        VStack {
            HouseListView(housesVM: viewModel)   
        }
        .onAppear {
            viewModel.fetchHouses()
       }
}
}

HouseListView(在ContentView中调用的视图:

代码语言:javascript
复制
struct HouseListView: View {
@ObservedObject var housesVM: ViewModel
@StateObject var locationManager = LocationManager()

var body: some View {
    ScrollView(.vertical, showsIndicators: false) {
        VStack(alignment: .leading) {
            ForEach(housesVM.info, id: \.id) { house in
                GetHouseCellView(
                    distance: Double(locationManager.distanceInKM(latitude: house.latitude, longitude: house.longitude)) ?? 0.00, //Here's the place where function is called
                    bedrooms: house.bedrooms)
            }
        }
    }
}
private func GetHouseCellView(distance: Double, bedrooms: Int) -> some View {
            
            HStack(spacing: 20) {
                Label("\(bedrooms)", image: "bed-2")
                Label("\(distance) km", image: "pin") //Here the final distance should be displayed, i.e 36,4 km
            }
        }

非常基本的ViewModel:

代码语言:javascript
复制
class ViewModel: ObservableObject {
    @Published var info: [Houses] = []
    func fetchHouses() {
        //URL & URLRequest here
            
            let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
                let decoder = JSONDecoder()
                do {
                    if let data = data {
                        let result = try decoder.decode([Houses].self, from: data) 
                        DispatchQueue.main.async {
                            self.info = result
                        }
                    }
                } catch {
                    print("whoopsie! There's an error: \(error.localizedDescription)")
                }
            }
            dataTask.resume()
        }
    }
    }

和一个LocationManager:

代码语言:javascript
复制
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    private let locationManager = CLLocationManager()
    @Published var locationStatus: CLAuthorizationStatus?
    @Published var lastLocation: CLLocation?

    override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    var statusString: String {
        guard let status = locationStatus else {
            return "unknown"
        }
        
        switch status {
        case .notDetermined: return "notDetermined"
        case .authorizedWhenInUse: return "authorizedWhenInUse"
        case .authorizedAlways: return "authorizedAlways"
        case .restricted: return "restricted"
        case .denied: return "denied"
        default: return "unknown"
        }
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        locationStatus = status
        print(#function, statusString)
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        lastLocation = location
        print(#function, location)
    }

    func distanceInKM(latitude: Int, longitude: Int) -> Double { //Here's the method I made to calculate an actual distance
        
        let houseCoordinates = CLLocation(latitude: CLLocationDegrees(latitude), longitude: CLLocationDegrees(longitude))
        
        let userCoordinates = CLLocation(latitude: lastLocation?.coordinate.latitude ?? 50, longitude: lastLocation?.coordinate.longitude ?? 30)
        let distance = userCoordinates.distance(from: houseCoordinates) / 1000 //.distance comes in meters so /1000 is to have a KM value
        
        let s = String(format: "%.0f", distance)
        
        return Double(s + "Km") ?? 35.5 // This value of 35.5 as placeholder is constantly displayed instead of the actual value
    }
}

这个功能逻辑是taken from this post

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-16 12:08:04

简单类型错误:

代码语言:javascript
复制
Double(s + "Km")

将始终返回0作为s+ "Km“不是有效的双。

只需返回:

代码语言:javascript
复制
Double(distance)

如果要返回字符串,请更改方法的类型并返回

代码语言:javascript
复制
s + "km"

编辑:如果要以km : in GetHouseCellView显示距离,请将距离标签更改为:

代码语言:javascript
复制
Label(String(format: "%.2f km", distance), image: "pin")

使用它时,最好将距离设置为双倍格式。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73735692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档