Search code examples
swiftsegueuitabbaritem

UIBarButtonItem not firing up selector action


I have a UIBarButtonItem:

let addProdButton = UIBarButtonItem(title: "+", style: UIBarButtonItemStyle.plain, target: self, action: #selector(AddProduct))

And the action it is connected to:

@objc func AddProduct()
    {
        performSegue(withIdentifier: "segue_to_add_product", sender: self)
    }

I am adding it to my navigationBar:

addProdButton.isEnabled = true
        self.navigationItem.leftBarButtonItem = addProdButton

And it shows and is clickable when I launch the app:

enter image description here

When I click it, it acts as clickable, but for some reason it doesn't fire up the action I created it with (Breakpoint isn't hit , segue isn't fired up). How do I make it work ?

More questions:

  1. How can I add a border to my UITabBarButton ?
  2. Is there a generic "Add" button in swift that I can use instead? (Or just the stye/picture)
  3. How can I enlarge the text inside the button ?

Edit:

I just noticed the button is clickable ONCE, and then the click animation no longer shows.

My viewDidLoad function:

override func viewDidLoad()
    {
        super.viewDidLoad()
        SetActivityIndicator()
        SetSearchBar()

        addProdButton.isEnabled = true
        self.navigationItem.leftBarButtonItem = addProdButton

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 200, height: 250)

        self.ProductsCollection = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)

        ProductsCollection.dataSource = self
        ProductsCollection.delegate = self
        ProductsCollection.register(ProductsCollectionViewCell.self, forCellWithReuseIdentifier: "product_collection_cell")
        ProductsCollection.backgroundColor = UIColor.clear

        let topConstraint = NSLayoutConstraint(item: ProductsCollection, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 20)
        let bottomConstraint = NSLayoutConstraint(item: ProductsCollection, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: -50) //leaving space for search field
        let leadingConstraint = NSLayoutConstraint(item: ProductsCollection, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 0)
        let trailingConstraint = NSLayoutConstraint(item: ProductsCollection, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 0)

        ProductsCollection.translatesAutoresizingMaskIntoConstraints = false

        self.view.addSubview(ProductsCollection)
        self.view.addConstraints([topConstraint, bottomConstraint, leadingConstraint, trailingConstraint])


    }

my SetSearchBar funciton:

internal func SetSearchBar()
    {
        self.productsSearchController.searchResultsUpdater = self
        self.productsSearchController.delegate = self
        self.productsSearchController.searchBar.delegate = self

        self.productsSearchController.hidesNavigationBarDuringPresentation = false
        self.productsSearchController.dimsBackgroundDuringPresentation = true
        self.productsSearchController.obscuresBackgroundDuringPresentation = false
        productsSearchController.searchBar.placeholder = "Search for tools and resources"
        productsSearchController.searchBar.sizeToFit()

        productsSearchController.searchBar.becomeFirstResponder()

        self.navigationItem.titleView = productsSearchController.searchBar


    }

Solution

  • The code you provided should be working so you need to provide more context (show more of your view controller class where this is implemented).

    UIKit provides a set of standard UIBarButtonItems called system items. These happen to include an 'add' item, which is displayed as a plus-sign and used throughout iOS. Using this item solves question 2 and 3.

    UIBarButtonItem has a convenience constructor for initialising a system item. See the working example below:

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let addProdButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addProduct))
            navigationItem.leftBarButtonItem = addProdButton
        }
    
        @objc func addProduct() {
            print("addProduct() called")
        }
    }