问题
I am trying to create - HeaderView which is subclass of UIView, it contains a close button and a title label.
class HeaderView: UIView {
private var titleLabel: UILabel!
private var closeButton: UIButton!
}
I don't want to add self as target of closeButton action but want to set myViewController as its target, moreover I want HeaderView class to be reusable.
So I declared a protocol:
protocol CloseViewProtocol {
func closeViewAction(sender: UIButton!)
}
And declared a variable like this:
class HeaderView: UIView {
private var titleLabel: UILabel!
private var closeButton: UIButton!
var closeButtonTarget: CloseViewProtocol?
}
to enforce (at compile time) that closeButtonTarget implements closeViewAction: method.
Now I can't do this:
closeButton.addTarget(closeButtonTarget, action: "closeViewAction:", forControlEvents: .TouchUpInside)
doing which compiler complains -
Cannot convert value of type 'CloseViewProtocol?' to expected argument type 'AnyObject?'
To resolve this I can do this:
let buttonTarget = closeButtonTarget as! UIViewController
closeButton.addTarget(buttonTarget, action: "closeViewAction:", forControlEvents: .TouchUpInside)
Is there any better way to achieve expected behavior?
回答1:
I like Andrius approach, but to answer the question, you have to add the class
keyword to your protocol’s inheritance list:
protocol CloseViewProtocol: class {
func closeViewAction(sender: UIButton!)
}
回答2:
This is a bit old school - protocol delegate, new patterns are more functional programming I would suggest using closures
var closeHanlder:()->Void?
Then have button as private var inside, and in View Controller do
headerViewInstance.closeHandler = self.handleCloseFunction
I should add that the button action gets handled in the headerView, whose action does what it needs and calls closeHandler?()
来源:https://stackoverflow.com/questions/32760481/swift-protocol-as-type-as-target-of-button-action