为什么新的 iOS 14 UIControl 动作语法如此糟糕?

mat*_*att 3 uicontrol ios uiaction ios14

iOS 14 中的新功能,我们可以将动作处理程序直接附加到 UIControl:

    let action = UIAction(title:"") { action in
        print("howdy!")
    }
    button.addAction(action, for: .touchUpInside)
Run Code Online (Sandbox Code Playgroud)

这很酷,但语法令人愤怒。我必须先形成 UIAction。我必须给 UIAction 一个标题,即使该标题永远不会出现在界面中。没有更好的办法吗?

mat*_*att 6

首先,您不需要提供标题。这是(现在)合法的:

    let action = UIAction { action in
        print("howdy!")
    }
    button.addAction(action, for: .touchUpInside)
Run Code Online (Sandbox Code Playgroud)

其次,您实际上并不需要单独的行来定义操作,因此您可以这样说:

    button.addAction(.init { action in
        print("howdy!")
    }, for: .touchUpInside)
Run Code Online (Sandbox Code Playgroud)

然而,这仍然令人气愤,因为现在我在addAction通话中遇到了一个闭包。它应该是一个尾随关闭!显而易见的解决方案是扩展:

extension UIControl {
    func addAction(for event: UIControl.Event, handler: @escaping UIActionHandler) {
        self.addAction(UIAction(handler:handler), for:event)
    }
}
Run Code Online (Sandbox Code Playgroud)

问题解决了!现在我可以用我一直被允许的方式说话了:

    button.addAction(for: .touchUpInside) { action in
        print("howdy!")
    }
Run Code Online (Sandbox Code Playgroud)

[额外信息:sender这个故事在哪里?它在 action 里面。UIAction 有一个sender属性。所以在那个代码中,action.sender是 UIButton。]