1

In Swift 4 I want to use an extension of UIBarButtonItem that instantiates a special UIBarButtonItem object.
Here is my code (only the essential statements):

import Foundation

extension UIBarButtonItem {

    convenience init(staticImageName: String) {
        let staticView = UIImageView.init(image: UIImage(named: staticImageName))
        self.init(customView: staticView)
//      further code…
    }

    override open var isEnabled: Bool { 
        didSet { 
            print("didSet called") // Should be replaced by other code…
        } 
    } 

} // extension UIBarButtonItem

This extension builds without problems.

However when I run the app, I get a runtime error at the statement
self.init(customView: staticView).
The log says:

-[UIBarButtonItem isEnabled]: unrecognized selector sent to instance 0x7fe20c505180

What is wrong with my code?

Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116
  • isEnabled is not a property of UIBarButtonItem. – Sagar Chauhan Dec 11 '17 at 14:47
  • @Jacky But it is a property of its superclass `UIBarItem` – Reinhard Männer Dec 11 '17 at 14:49
  • Please refer this, may be help you : https://stackoverflow.com/questions/3784112/how-to-disable-uibarbuttonitem – Sagar Chauhan Dec 11 '17 at 14:54
  • 1
    Extensions are for adding new functionality. Extensions must not be used to override anything. Create a subclass if you want to override. From the Swift book: *"“Extensions can add new functionality to a type, but they cannot override existing functionality.”* – rmaddy Dec 11 '17 at 15:55
  • Had similar issue. It seems UIBarButtonItem's `isEnabled` doesn't work as expected starting from Xcode 9 / iOS SDK 11. I changed UIBarButtonItem to use UIButton as a custom view to be able to use UIButton's `isEnabled` – Seryozha Dec 11 '17 at 16:41
  • @rmaddy Thanks for clarification. The question then, however, is, why this is accepted by the compiler. Actually, my code was previously `override var isEnabled: Bool {...}`, and the compiler suggested `Overriding var must be as accessible as the declaration it overrides`and suggested as a fix to insert `open`. – Reinhard Männer Dec 11 '17 at 20:48
  • I have no idea why the Swift compiler allows `override` in an extension since extensions are not supposed to be used to override anything. I'd call it a bug. – rmaddy Dec 11 '17 at 20:51
  • @rmaddy Anyway, this is the solution. Please post it as an answer, so that I can close the question! – Reinhard Männer Dec 11 '17 at 20:53

1 Answers1

0

Extensions are not supposed to be used to override any existing functionality. Extensions are only supposed to be used to add new functionality.

For the Extensions chapter in the Swift book:

“Extensions can add new functionality to a type, but they cannot override existing functionality.”

So the proper solution is to subclass UIBarButtonItem if you wish to override existing functionality. Then use the subclass wherever you need it.

rmaddy
  • 314,917
  • 42
  • 532
  • 579