再见c罗再见梅西
Up until now, iOS developers had to use the Target-Action pattern to set actions on UIKit controls. It wasn’t really a Swifty way of setting actions since selectors were born in Objective-C.
到目前为止,iOS开发人员必须使用Target-Action模式在UIKit控件上设置操作。 由于选择器是在Objective-C中诞生的,所以这并不是设置动作的快速方法。
Until iOS 13, for most UIControls
, you’d have to addTarget
, set a selector function name, and define that function somewhere else in your code. Not only was this tedious, but it also required setting default actions for selectors when handling multiple buttons or segmented controls. This could pose problems if a UIButton
or UISegmentedControl
element was modified, as we’d have to address the selector handler function and ensure there was a default
case.
在iOS 13之前,对于大多数UIControls
,您必须addTarget
,设置选择器函数名称,并在代码中的其他位置定义该函数。 这不仅繁琐,而且在处理多个按钮或分段控件时还需要为选择器设置默认操作。 如果修改了UIButton
或UISegmentedControl
元素,这可能会引起问题,因为我们必须处理选择器处理程序函数,并确保存在default
情况。
iOS 14 changes the way we set actions on some of our UI elements by providing initializers to set UIAction
. In doing so, we can get rid of event handlers, as the UIAction
's handler automatically takes care of it.
iOS 14通过提供初始化程序来设置UIAction
,从而改变了我们对某些UI元素设置操作的方式。 这样,我们可以摆脱事件处理程序,因为UIAction
的处理程序会自动处理它。
So, it’s time to say goodbye to the iOS 13 and older ways of setting target actions:
因此,是时候告别iOS 13和更旧的设置目标操作的方法了:
button.addTarget(self, action: #selector(test(sender:)), for: .touchUpInside)@objc
func test(sender: UIButton){...}
Let’s look at the new way of setting UIAction
on buttons and segmented controls and also how to set control events with UIAction
.
让我们看看在按钮和分段控件上设置UIAction
的新方法,以及如何使用UIAction
设置控件事件。
iOS 14的新UIAction初始化程序 (iOS 14's New UIAction Initializers)
All UI controls ranging from DatePicker
to ColorPicker
and UIBarButtonItems
can be initialized with a UIAction
in iOS 14.
可以使用iOS 14中的UIAction
初始化从DatePicker
到ColorPicker
和UIBarButtonItems
所有UI控件。
UIButton
now provides primaryAction
as an additional argument in its initializer, which lets us set the button title
, image
, state
, identifier
, and the action handler. The following UIAction
initializer inside UIButton
shows the basic setup:
UIButton
现在在其初始值设定项中提供primaryAction
作为附加参数,使我们可以设置按钮的title
, image
, state
, identifier
和action处理程序。 UIButton
中的以下UIAction
初始化程序显示了基本设置:

UISegmentedControl
introduces an actions
argument that lets you set an array of UIActions
— one for each item:
UISegmentedControl
引入了一个actions
参数,该参数可让您设置一组UIActions
—每个项目一个:
使用addActions设置控件事件的UIAction (Use addActions to set UIActions for Control Events)
The important thing to notice about UIAction
is that it inherits from the UIMenuElement
class.
关于UIAction
的重要注意事项是它继承自UIMenuElement
类。
It’s worth noting that UIAction
states aren’t UIControl
events and it’s designed for setting UIMenus
on UIControls
.
值得注意的是, UIAction
状态不是UIControl
事件,它是为在UIControls
上设置UIMenus
而设计的。
Since we can’t really set control events in UIControl
initializers, how can you set UIAction
for specific control events?
由于我们实际上无法在UIControl
初始化程序中设置控件事件,因此如何为特定控件事件设置UIAction
?
Thankfully, we also have an addAction
method that lets you set the UIAction
handler based on control events:
幸运的是,我们还有一个addAction
方法,可让您根据控件事件设置UIAction
处理程序:
button.addAction(UIAction(title: "Click Me", handler: { _ in print("Hi")}), for: .menuActionTriggered)
menuActionTriggered
is a new control event available in UIButton
with iOS 14. It’s invoked when a menu is displayed on the press of a UIButton
.
menuActionTriggered
是iOS 14的UIButton
可用的新控件事件,当按下UIButton
时显示菜单时将调用该事件。
将UIAction与UITextField一起使用 (Using UIAction With UITextField)
For a UITextField
control, where we’d want to listen to events like editingDidBegin
, setting a primaryAction
in the initializer wouldn’t help and we’d have to leverage the addAction
method to listen to specific control events:
对于UITextField
控件,我们希望在其中监听诸如editingDidBegin
事件,在初始化程序中设置primaryAction
将无济于事,我们必须利用addAction
方法来监听特定的控件事件:

We can follow the same approach for setting actions on different control events.
我们可以采用相同的方法来针对不同的控制事件设置动作。
总结思想 (Closing Thoughts)
Remember, UIAction
is useful for setting primary actions on all UIControl
initializers. But if you’re looking to set actions for specific UIControl
events, implementing the addAction
method is the way to go.
请记住, UIAction
对于在所有UIControl
初始化程序上设置主要操作很有用。 但是,如果您要为特定的UIControl
事件设置操作,则可以采用addAction
方法。
UIAction
was basically used in ContextMenus with iOS 13 for setting menu actions. Having exposed it to the UIControls
for tap and other events is a design that’s up for discussion considering there are so many menu-related initializers exposed. Regardless, going away from the Target-Action pattern is a good move and much-needed change for Swift developers.
UIAction
基本上在iOS 13的ContextMenus中用于设置菜单操作。 考虑到暴露了太多与菜单相关的初始化程序,将其公开给UIControls
进行敲击和其他事件的设计值得讨论。 无论如何,摆脱Target-Action模式是一个不错的举动,对Swift开发人员来说是急需的更改。
While implementing UIAction
handlers, you need to be wary of retain cycles that could arise in closures.
在实现UIAction
处理程序时,需要警惕闭包中可能出现的保留周期。
Besides UIAction
, UIMenu
is also exposed to all UIControls
in UIKit starting iOS 14. We’ll see how to do that and other changes in UIMenu
in the next article. Stay tuned and thanks for reading.
除了UIAction
之外,从iOS 14开始, UIMenu
还暴露给UIKit中的所有UIControls
。我们将在下一篇文章中了解如何执行此操作以及UIMenu
中的其他更改。 请继续关注,并感谢您的阅读。
翻译自: https://medium.com/better-programming/goodbye-target-actions-hello-uiactions-a60e1e2052d5
再见c罗再见梅西