Swift以编程方式为带按钮的按钮创建函数
发布时间:2020-12-14 04:44:18 所属栏目:百科 来源:网络整理
导读:在 Swift中,您可以为这样的按钮创建一个函数: button.addTarget(self,action: #selector(buttonAction),forControlEvents: .TouchUpInside) 但有没有办法可以做到这样的事情: button.whenButtonIsClicked({Insert code here}) 这样我甚至没有为按钮声明一
在
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) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |