Search code examples
swiftxcodegoogle-maps-sdk-ios

How to change the function of a UIBarButtonItem on event in Swift


I've been following this Youtube tutorial from Let's Build That App to achieve a step by step navigation system using the Google Maps SDK. I want to be able to change the programmatically-generated 'next' UIBarButtonItem to a 'done' button on the last map location and use this to go back to a previous ViewController.

What's the correct method of going about this using Swift?

https://www.youtube.com/watch?v=8wPjCdDn2wo

My code:

    navigationItem.rightBarButtonItem = UIBarButtonItem(
            title: "Next",
            style: .plain,
            target: self,
            action: #selector(nextLocation)
        )
}

func nextLocation() {

    if currentDestination == nil {
        currentDestination = destinations.first


    }
    else {

        if let index = destinations.index(of: currentDestination!), index < destinations.count - 1{
            currentDestination = destinations[index + 1]

        }
    }

    setMapCamera()
}

private func setMapCamera() {
    CATransaction.begin()
    CATransaction.setValue(2, forKey: kCATransactionAnimationDuration)
    mapView?.animate(to: GMSCameraPosition.camera(withTarget: currentDestination!.location, zoom: currentDestination!.zoom))

    CATransaction.commit()
    let marker = GMSMarker(position: currentDestination!.location)
    marker.title = currentDestination?.name
    marker.map = mapView

}

/* My incorrect code */

func lastLocation() {

    if currentDestination == destinations.last {
        navigationItem.rightBarButtonItem = UIBarButtonItem(
            title: "Finish",
            style: .plain,
            target: "myItinerary",
            action: #selector(lastLocation)
        )
    }
}

Solution

  • I Hope this will help you : First : Detect Last location or bar button click after last location to change bar button label to "Done". Then set action to the button after button "Done" clicked change again to "Next" and set destination counter to first value.

    func next() {
    
       if currentDestination == nil {
           currentDestination = destinations.first
       } else {
           if let index = destinations.index(of: currentDestination!), index < destinations.count - 1 {
               currentDestination = destinations[index + 1]
           }
           else {
               // After last Location change button title to "Done"
               navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(lastLocation))
           }
    
       }
       setMapCamera()
    }
    
    func lastLocation() {
        currentDestination = destinations.first // Set destinations counter to First value 
        // Change Title of Bar Button
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(ViewController.next as (ViewController) -> () -> ()))
    } 
    

    If you want to go backward location (In reverse) then :

    func lastLocation() {
        currentDestination = destinations.last
        destinations = destinations.reversed()
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(ViewController.next as (ViewController) -> () -> ()))
    }