簡體   English   中英

無法使用 mapKit 將坐標從 ViewController 發送到另一個具有委托的 viewController

[英]Unable to send coordinates from ViewController with mapKit to another viewController with delegate

我是 Swift 和 iOS 開發的新手。 我有一個問題,我通過標簽欄導航控制器連接了三個 viewController。 第一個 viewController 現在是空的,沒有使用。 在 secondViewController 中,我使用來自天氣 API 的數據更新 UI。 在第三個視圖控制器中,我有一張地圖。 當我訪問地圖時,我需要坐標來更新 secondViewController 中的 url。

我想要實現的是在第三個視圖控制器中檢索當前的緯度和經度(沒問題),但我無法通過委托發送這些值以觸發第二個視圖控制器中的函數,從而更新那里的變量. secondViewController 中的委托函數沒有被觸發。 我究竟做錯了什么? 或者甚至有可能這樣做嗎?

兩個視圖控制器的代碼如下:

secondViewController(這是我需要來自thirdViewController 中的地圖的值的地方)

import UIKit

class SecondViewController: UIViewController, MapViewControllerDelegate {

    var forecastData: [ForecastData] = []
    var currentLat: String = "59.911166"
    var currentLon: String = "10.744810"
    
    @IBOutlet weak var tableView: UITableView!
    
    var weatherManager = WeatherManager()
    var mapViewController = ThirdViewController()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mapViewController.delegate = self
        weatherManager.delegate = self
        weatherManager.fetchWeather(latitude: currentLat, longitude: currentLon)
        tableView.backgroundView = UIImageView(image: UIImage(named: "background"))
        tableView.dataSource = self
        tableView.register(UINib(nibName: "WeatherCell", bundle: nil), forCellReuseIdentifier: "WeatherCell")
        
    }
    
    func viewDidAppear() {
        weatherManager.fetchWeather(latitude: currentLat, longitude: currentLon)
        
    }
    
    
    // THIS FUNCTION SHOULD BE TRIGGERED BUT DOESN'T
    
    func mapViewController(latitude: String, longitude: String) {
        currentLat = latitude
        currentLon = longitude
        print(currentLat)
        print(currentLon)
        print("DELEGATE METHOD TRIGGERED")
    }

}

//MARK: - WeatherManagerDelegate

extension SecondViewController: WeatherManagerDelegate {
    
    func didUpdateWeather(_ weatherManager: WeatherManager, weather: WeatherModel) {
        
        forecastData.append(ForecastData(timespan: "Nå", precipitation: "", tempOrWeather: "Temperatur", tempWeatherLabel: "\(weather.temperatureNow)" + " " + "\(weather.tempUnits)"))
        
        forecastData.append(ForecastData(timespan: "Neste Time", precipitation: "\(weather.precipitationNext1H)" + " " + "\(weather.precipUnits)", tempOrWeather: "vær", tempWeatherLabel: String(weather.conditionNext1H) ))
        
        forecastData.append(ForecastData(timespan: "Neste 6 timer", precipitation: "\(weather.precipitationNext6H)" + " " + "\(weather.precipUnits)", tempOrWeather: "vær", tempWeatherLabel: String(weather.conditionNext6H)))
        
        forecastData.append(ForecastData(timespan: "Neste 12 timer", precipitation: "", tempOrWeather: "vær",  tempWeatherLabel: String(weather.conditionNext12H)))
        
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
        
    }
    
    func didFailWithError(error: Error) {
        print(error)
    }
}

extension SecondViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return forecastData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WeatherCell", for: indexPath)
        as! WeatherCell
        cell.TimeframeLabel.text = forecastData[indexPath.row].TimeframeLabel
        cell.TempLabel.text = forecastData[indexPath.row].TempLabel
        cell.WeatherCodeLabel.text = forecastData[indexPath.row].WeatherCodeLabel
        cell.PrecipitationLabel.text = forecastData[indexPath.row].PrecipitationLabel
        return cell
    }
}

第三視圖控制器(這是我嘗試通過委托傳遞坐標值的地方)

import UIKit
import MapKit
import CoreLocation

protocol MapViewControllerDelegate {
    func mapViewController(latitude: String, longitude: String)
}

class ThirdViewController: UIViewController, MKMapViewDelegate {
    
    var currentLat = ""
    var currentLon = ""
    @IBOutlet weak var mMapView: MKMapView!
    fileprivate let locationManager: CLLocationManager = CLLocationManager()
    var delegate: MapViewControllerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
        locationManager.startUpdatingLocation()
        
        mMapView.showsUserLocation = true
               
        currentLat = String((locationManager.location?.coordinate.latitude)!)
        currentLon = String((locationManager.location?.coordinate.longitude)!)
        
        print(currentLat)
        print(currentLon)
        
        //delegate?.mapViewController(latitude: "TESTlon", longitude: "TESTlati")
    }
    
    override func viewDidAppear(_ animated: Bool) {
        updateWeatherView()
    }
    
    // THIS SHOULD TRIGGER THE DELEGATE FUNCTION IN SECOND VIEW CONTROLLER AND PASS THE DATA ALONG
    func updateWeatherView() {
        delegate?.mapViewController(latitude: "TESTlon", longitude: "TESTlati")
    }
    
}


我嘗試了不同的方法,但似乎沒有任何效果,secondViewController 中的委托函數沒有被觸發。 同樣,我對此很陌生,所以也許這是一件簡單的事情。 在此先感謝您的幫助! 另外,如果有幫助,這是我的故事板的屏幕截圖:

故事板截圖

正如@Duncan C 所說,做

var weatherManager = WeatherManager()
var mapViewController = ThirdViewController()

只需創建這些視圖控制器的新實例——這些與您已有的完全無關。 當然,如果您執行mapViewController.delegate = self ,則您正在設置mapViewController的委托...但mapViewController不是您想要的視圖控制器。

要獲得您想要的視圖控制器,您可以訪問標簽欄控制器的視圖控制器(當您在故事板中創建它們時會自動為您創建),然后選擇正確的:

if 
    let viewControllers = self.tabBarController?.viewControllers, 
    viewControllers.count >= 3,
    let thirdViewController = viewControllers[2] as? ThirdViewController /// [2] because that's the third view controller in the array, which is the one you want
{
    thirdViewController.delegate = self
}

self.tabBarController可能為零,因此您需要解開它。 然后,您應該確保有 3 個以上的視圖控制器。 最后,您需要將您需要的視圖控制器( self.tabBarController?.viewControllers[2] )轉換為ThirdViewController 然后,您可以將委托設置為該視圖控制器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM