Search code examples
iosswift3uibarbuttonitemuitoolbar

Change Toolbar Button


I hit a road bump trying to change the toolbar button of type UIBarButtonItem during runtime.

I've created programatically a Toolbar for a given text view and I want to change the button image when it's pressed, like if it has a toggle on image and a toggle off one.

I'll explain:

Here I create the toolbar with the desired buttons

func configureToolbar(forTextView textView: UITextView) {

    toolbar?.barStyle = UIBarStyle.default
    toolbar?.items = [
        UIBarButtonItem.init(image: UIImage.init(named: "bold_unselected"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.didTapBold(sender:))),
        UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
        UIBarButtonItem(title: "Italic", style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.didTapItalic(sender:))),
        UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
        UIBarButtonItem(title: "Underline", style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.dismissKB))]
    toolbar?.sizeToFit()

    for (index,item) in (toolbar?.items?.enumerated())! {
        item.tag = index
    }

    // Adds a view as a upper border line
    let border = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 0.5))
    border.backgroundColor = UIColor.lightGray
    toolbar?.addSubview(border)

    // Configures the toolbar
    toolbar?.backgroundColor = UIColor.white
    toolbar?.barTintColor = UIColor.white
    toolbar?.tintColor = UIColor.black
    toolbar?.clipsToBounds = true

    // Adds to the super view;
    textView.inputAccessoryView = toolbar
}

Here's the bold button function

func didTapBold(sender: UIBarButtonItem) {

    typeface.isBold = typeface.isBold! ? false : true // true -> false -> true
    toggleButton(button: sender, status: typeface.isBold!)
}

Here's where I want to change the button 'status' ON - OFF

func toggleButton(button: UIBarButtonItem, status: Bool) {
    // changes the button appearance
    switch button.tag {
    case 0:
        print("bold")
        print("status \(status)")
        if status {
            button.image = UIImage.init(named: "bold_selected")
        } else {
            button.image = UIImage.init(named: "bold_unselected")
        }

    case 2:
        print("bla bla bla")

    case 4:
        print("bla bla bla 2")

    default:
        print("default value called")
    }
}

For some reason, I can't change the image to the one that I want to, but I can change to another one.

I've read the Human Interface Guidelines and can't find which are the recommended image size to the toolbar, but after searching I've read in some websites that is 20x20, can someone confirm it?

There are the default image and the selected one.

unselected

selected

UPDATE Somehow it seems that I can't add any coloured icon/image to the toolbar. Just tried to add a different icon and it just showed up as a black dot.


Solution

  • So I have found the solution, which is pretty simple but it wasn't easy to find.

    If you want to add coloured icons/images to your toolbar, when you're adding the image don't forget to set the rendering mode property to always original.

    Se corrected code now should be:

    //when setting the toolbar icons
    toolbar?.items = [UIBarButtonItem.init(image: UIImage.init(named: "bold_unselected")?.withRenderingMode(.alwaysOriginal), style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.didTapBold(sender:)))]
    

    Or instantiate your images to

    let img = UIImage(named: "image").withRenderingMode(.alwaysOriginal)
    let barBtnItm = UIBarButtonItem.init(image: img, style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.didTapBold(sender:)))
    

    Hope it helps