在
Swift中,您可以为这样的按钮创建一个函数:
button.addTarget(self,action: #selector(buttonAction),forControlEvents: .TouchUpInside)
但有没有办法可以做到这样的事情:
button.whenButtonIsClicked({Insert code here})
解决方法
创建自己的UIButton子类来执行此操作:
class MyButton: UIButton { var action: (() -> Void)? func whenButtonIsClicked(action: @escaping () -> Void) { self.action = action self.addTarget(self,action: #selector(MyButton.clicked),for: .touchUpInside) } // Button Event Handler: // I have not marked this as @IBAction because it is not intended to // be hooked up to Interface Builder @objc func clicked() { action?() } }
当您以编程方式创建按钮然后调用whenButtonIsClicked来设置其功能时,将MyButton替换为UIButton.
您还可以在故事板中使用UIButtons(只需将其类更改为MyButton),然后在viewDidLoad中调用whenButtonIsClicked.
@IBOutlet weak var theButton: MyButton! var count = 0 override func viewDidLoad() { super.viewDidLoad() // be sure to declare [uNowned self] if you access // properties or methods of the class so that you // don't create a strong reference cycle theButton.whenButtonIsClicked { [uNowned self] in self.count += 1 print("count = \(self.count)") }
一个更有能力的实施
认识到程序员可能想要处理比.touchUpInside更多的事件这一事实,我写了这个更强大的版本,它支持每个UIButton的多个闭包和每个事件类型的多个闭包.
class ClosureButton: UIButton { private var actions = [UInt : [((UIControl.Event) -> Void)]]() private let funcDict: [UInt : Selector] = [ UIControl.Event.touchCancel.rawValue: #selector(eventTouchCancel),UIControl.Event.touchDown.rawValue: #selector(eventTouchDown),UIControl.Event.touchDownRepeat.rawValue: #selector(eventTouchDownRepeat),UIControl.Event.touchUpInside.rawValue: #selector(eventTouchUpInside),UIControl.Event.touchUpOutside.rawValue: #selector(eventTouchUpOutside),UIControl.Event.touchdragenter.rawValue: #selector(eventTouchdragenter),UIControl.Event.touchDragExit.rawValue: #selector(eventTouchDragExit),UIControl.Event.touchDragInside.rawValue: #selector(eventTouchDragInside),UIControl.Event.touchDragOutside.rawValue: #selector(eventTouchDragOutside) ] func handle(events: [UIControl.Event],action: @escaping (UIControl.Event) -> Void) { for event in events { if var closures = actions[event.rawValue] { closures.append(action) actions[event.rawValue] = closures } else { guard let sel = funcDict[event.rawValue] else { continue } self.addTarget(self,action: sel,for: event) actions[event.rawValue] = [action] } } } private func callActions(for event: UIControl.Event) { guard let actions = actions[event.rawValue] else { return } for action in actions { action(event) } } @objc private func eventTouchCancel() { callActions(for: .touchCancel) } @objc private func eventTouchDown() { callActions(for: .touchDown) } @objc private func eventTouchDownRepeat() { callActions(for: .touchDownRepeat) } @objc private func eventTouchUpInside() { callActions(for: .touchUpInside) } @objc private func eventTouchUpOutside() { callActions(for: .touchUpOutside) } @objc private func eventTouchdragenter() { callActions(for: .touchdragenter) } @objc private func eventTouchDragExit() { callActions(for: .touchDragExit) } @objc private func eventTouchDragInside() { callActions(for: .touchDragInside) } @objc private func eventTouchDragOutside() { callActions(for: .touchDragOutside) } }
演示
class ViewController: UIViewController { var count = 0 override func viewDidLoad() { super.viewDidLoad() let button = ClosureButton(frame: CGRect(x: 50,y: 100,width: 60,height: 40)) button.setTitle("press me",for: .normal) button.setTitleColor(.blue,for: .normal) // Demonstration of handling a single UIControl.Event type. // If your closure accesses self,be sure to declare [uNowned self] // to prevent a strong reference cycle button.handle(events: [.touchUpInside]) { [uNowned self] _ in self.count += 1 print("count = \(self.count)") } // Define a second handler for touchUpInside: button.handle(events: [.touchUpInside]) { _ in print("I'll be called on touchUpInside too") } let manyEvents: [UIControl.Event] = [.touchCancel,.touchUpInside,.touchDown,.touchDownRepeat,.touchUpOutside,.touchdragenter,.touchDragExit,.touchDragInside,.touchDragOutside] // Demonstration of handling multiple events button.handle(events: manyEvents) { event in switch event { case .touchCancel: print("touchCancel") case .touchDown: print("touchDown") case .touchDownRepeat: print("touchDownRepeat") case .touchUpInside: print("touchUpInside") case .touchUpOutside: print("touchUpOutside") case .touchdragenter: print("touchdragenter") case .touchDragExit: print("touchDragExit") case .touchDragInside: print("touchDragInside") case .touchDragOutside: print("touchDragOutside") default: break } } self.view.addSubview(button) } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。