You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS天气App中Segue无法按条件正常工作问题求助

iOS Weather App Segue 触发与数据传递问题排查与修复

你遇到的Segue无法正常触发和传递数据的问题,我帮你排查了代码里的几个关键问题,下面逐一分析并给出修复方案:

问题1:prepare(for:sender:) 方法未正确重写

你写的prepare方法签名有误,导致系统根本不会调用这个方法,自然无法传递数据:

// 错误写法
func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {

正确的写法需要加上override关键字,并且sender的类型是Any?而不是AnyObject?:

// 正确写法
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

问题2:主动调用performSegue与shouldPerformSegue的逻辑冲突

当你主动调用performSegue(withIdentifier:sender:)时,系统会先触发shouldPerformSegue的判断。虽然你在回调里设置了userInputLocationSuccess = true,但有两个细节需要调整:

  • 在goButtonTapped的异步回调中,你先弹出了Alert再调用performSegue,但Alert弹出后会阻断UI交互,Segue的触发会被延迟。建议去掉Alert后直接执行Segue,或者在Alert的确认回调里触发Segue。
  • 确保shouldPerformSegue里的状态判断逻辑和主动触发时的状态一致,比如userInputLocationSuccess在验证通过后确实被设为true(这部分你已经用DispatchQueue.main.async处理了线程问题,是正确的)。

问题3:Core Location 逻辑中的冗余操作

在getMyLocationWeatherTapped里你初始化了locationManager并调用requestLocation(),但在didChangeAuthorization里又调用startUpdatingLocation(),这会导致位置更新被重复触发。建议调整逻辑:

@IBAction func getMyLocationWeatherTapped(_ sender: UIButton) {
    self.locationManager = CLLocationManager()
    self.locationManager?.delegate = self
    self.locationManager?.desiredAccuracy = kCLLocationAccuracyHundredMeters
    let status = CLLocationManager.authorizationStatus()
    if status == .authorizedWhenInUse {
        self.locationManager?.requestLocation()
    } else {
        self.locationManager?.requestWhenInUseAuthorization()
    }
}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedWhenInUse {
        self.locationManager?.requestLocation() // 用requestLocation替代startUpdatingLocation,只获取一次位置
    } else if status == .denied || status == .restricted {
        presentAlert("Location Access Denied", message: "Please enable location access in settings", cancelTitle: "OK")
    }
}

问题4:错误处理中的Segue调用错误

在locationManager(_:didFailWithError:)里,你错误调用了shouldPerformSegue(这只是判断方法,不是触发方法),而且Segue标识符也写错了(应该是coreLocationButtonSegue而不是coreLocationButton),这里应该直接提示用户,不需要触发Segue:

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    SVProgressHUD.dismiss()
    presentAlert("Location Not Found", message: "Provide zipcode, address or city", cancelTitle: "OK")
    self.coreLocationSuccess = false // 重置状态
}

修改后的完整关键代码示例

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    print("ENTERED INTO THE SEGUE FUNCTION")
    if segue.identifier == "goButtonSegue"{
        if let destinationVC = segue.destination as? WeatherForecastViewController {
            guard let neededZipcode = self.zipCodeTextField.text else {print("neededZipcode did not unwrap"); return}
            destinationVC.zipCode = neededZipcode
        }
    } else if segue.identifier == "coreLocationButtonSegue"{
        if let destinationVC = segue.destination as? WeatherForecastViewController {
            guard let userLocation = currentLocation else {print("did not pass user location"); return}
            destinationVC.coordinateHolder = userLocation // 这里用userLocation更清晰
        }
    }
}

@IBAction func goButtonTapped(_ sender: Any) {
    SVProgressHUD.show(withStatus: "Finding Your Location")
    guard let userText = self.zipCodeTextField.text, !userText.isEmpty else {
        SVProgressHUD.dismiss()
        presentAlert("Invalid Input", message: "Please enter a zipcode", cancelTitle: "OK")
        return
    }
    GoogleCoordinateAPIClient.isAddressValid(zipCode: userText) { (boolValue) in
        DispatchQueue.main.async {
            SVProgressHUD.dismiss()
            if boolValue {
                self.userInputLocationSuccess = true
                // 直接触发Segue,或者在Alert的确认回调里执行
                self.performSegue(withIdentifier: "goButtonSegue", sender: self)
            } else {
                self.userInputLocationSuccess = false
                self.presentAlert("Invalid Input", message: "Please re-enter valid input", cancelTitle: "OK")
            }
        }
    }
}

按照这些修改后,Segue应该能正常触发并传递数据了。

内容的提问来源于stack exchange,提问作者Sara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:38:29