首页 > 解决方案 > 我无法从另一个 ViewController 执行功能

问题描述

有人可以帮我在另一个 VC 中执行一个 VC 的功能吗?一旦我按下第二个 VC 中的按钮,就需要执行第一个 VC 中的功能。我正在尝试使用“viewcontroller().function()”函数,但它不能正常工作,打印和基本的东西可以工作,但是当涉及到像绘图方向这样的东西时,它就不能工作了。

绘制方向的函数是:

func directionToPin() {

    guard let currentPlacemark = currentPlacemark else {
        print("Error, the current Placemark is: \(self.currentPlacemark)")
        return
    }

    let directionRequest = MKDirections.Request()
    let destinationPlacemark = MKPlacemark(placemark: currentPlacemark)

    directionRequest.source = MKMapItem.forCurrentLocation()
    directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
    directionRequest.transportType = .walking

    //calculate route
    let directions = MKDirections(request: directionRequest)
    directions.calculate{ (directionsResponse, error) in

        guard let directionsResponse = directionsResponse else {
            if let error = error {
                print("error getting directions: \(error.localizedDescription)")
            }
            return
         }

        let route = directionsResponse.routes[0]

        if self.drawedDriection == false {
            self.drawedDriection = true

            if self.didSelectAnnotation == true {
                self.mapView.addOverlay(route.polyline, level: .aboveRoads)self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonRed")?.withRenderingMode(.alwaysOriginal), for: .normal)
                        self.mapView.setRegion(MKCoordinateRegion(routeRect), animated: true)
                    }
                } else {
                    self.drawedDriection = false
                    self.mapView.removeOverlays(self.mapView.overlays)
                    if self.didSelectAnnotation == true {
                        self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonBlue")?.withRenderingMode(.alwaysOriginal), for: .normal)
                    } else {
                        self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonGray")?.withRenderingMode(.alwaysOriginal), for: .normal)
                    }
                }
            }
        }

按下按钮后,我将在第二个 VC 中调用该函数:

@IBAction func directionButton(_ sender: Any) {
    MapViewController().directionToPin()
} 

当我运行应用程序并按下按钮时,currentPlacemark为零,如果我通过我的第一个 VC 中的按钮运行相同的功能(内部带有 directionToPin 功能的 VC)

如果您需要,这是我的仓库:https ://github.com/octavi42/xCodeMapsApp

谢谢!

标签: iosswiftfunctionviewcontroller

解决方案


我认为你需要使用协议和委托来实现你想要的。

@IBAction func directionButton(_ sender: Any) {
    MapViewController().directionToPin()
} 

在上面的代码片段中,您正在实例化MapViewController的一个新实例,该实例在初始化时会重置currentPlacemark,因此您遇到了nil

我的建议是创建一个新协议来从MapViewControllerCardViewController进行通信,就像这样

在MapViewController.swift中添加这些

protocol MapNavigationDelegate: AnyObject {
    func didTapDirectionButton()
}

class MapViewController: UIViewController {
    // .... Some code ....

    override func viewDidLoad() {
        // . .... Some more code .......
        navigationBarController.mapNavigationDelegate = self
    }
}

extension MapViewController: MapNavigationDelegate {
    func didTapDirectionButton() {
        self.directionToPin()
    }
}

在CardViewController.swift中添加这些

class CardViewController: UIView {
    // .... Some Code ....
    weak var mapNavigationDelegate: MapNavigationDelegate!

    @IBAction func directionButton(_ sender: Any) {
        self.mapNavigationDelegate.didTapDirectionButton()
    }
}

推荐阅读