加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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)
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读