Yetispapa
Yetispapa

Reputation: 2296

Swift - Prevent back event in UIViewController

i have a question about canceling the back event triggered from the back-button in a UIViewController. In Objective-C there was the following extension. I don't really know how to convert it to swift. What I tried to far was to override the backBarButton with my own functions but it's not working:

    navigation.backBarButtonItem?.action = #selector(MyController.back)
    navigation.backBarButtonItem?.target = self

I searched for something like a delegate function but I can't find anything for the backButton.

Upvotes: 5

Views: 5235

Answers (3)

0x384c0
0x384c0

Reputation: 2294

When i faced with this problem, i rewrited this extension to Swift 3

This solution keeps system back button with "<"

public protocol VCWithBackButtonHandler {
     func shouldPopOnBackButton() -> Bool
}

extension UINavigationController: UINavigationBarDelegate  {
    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {

        if viewControllers.count < (navigationBar.items?.count) ?? 0 {
            return true
        }

        var shouldPop = true
        let vc = self.topViewController

        if let vc = vc as? VCWithBackButtonHandler {
            shouldPop = vc.shouldPopOnBackButton()
        }

        if shouldPop {
            DispatchQueue.main.async {[weak self] in
                _ = self?.popViewController(animated: true)
            }
        } else {
            for subView in navigationBar.subviews {
                if(0 < subView.alpha && subView.alpha < 1) {
                    UIView.animate(withDuration: 0.25, animations: {
                        subView.alpha = 1
                    })
                }
            }
        }

        return false
    }
}

Usage:

class ViewController: UIViewController,VCWithBackButtonHandler{
    public func shouldPopOnBackButton() -> Bool {
        return false
    }
}

Upvotes: 9

harshal jadhav
harshal jadhav

Reputation: 5684

You need to override the backBarButtonItem by using the navigationItem's leftBarButtonItem. This replaces the back button in the navigation bar, and you can specify the custom selector to call:

self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .Done, target: self, action: #selector(self.backAction(sender:)))

func backAction(sender: AnyObject) {
     //Your Code
}

Upvotes: 6

KKRocks
KKRocks

Reputation: 8322

Try this:

override func viewDidLoad {
        super.viewDidLoad()
        self.navigationItem.hidesBackButton = true
        let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Bordered, target: self, action: "back:")
        self.navigationItem.leftBarButtonItem = newBackButton
    }

func back(sender: UIBarButtonItem) {
    // Perform your custom actions
    // ...
    // Go back to the previous ViewController
    self.navigationController?.popViewControllerAnimated(true)
}

Upvotes: 0

Related Questions