Actions
Actions为一组扩展,用于向UIView
和UIControl
实例中添加闭包。同时也为UIBarButtonItem
、UIGestureRecognizer
、Timer
和NotificationCenter
提供了一些方法,允许使用闭包而不是目标/操作对来使用它们。
使用Actions,您可以轻松地这样添加操作
// UIView
let imageView = UIImageView()
imageView.add(gesture: .swipe(.Left)) {
print("Image swipped")
}
// UIControl
let button = UIButton()
button.add(event: .touchUpInside) {
print("Button tapped")
}
let textField = UITextField()
textField.throttle(.editingChanged, interval: 0.5) { (textField: UITextField) in
print("Text changed to: \(textField.text)")
}
// UIGestureRecognizer
let gestureRecognizer = UIRotationGestureRecognizer {
print("Gesture triggered")
}
// UIBarButtonItem
let barButtonItem = UIBarButtonItem(title: "Title") {
print("Bar button item tapped")
}
// Timer (formally NSTimer)
Timer.scheduledTimer(timeInterval: 5) {
print("timer fired")
}
// NotificationCenter (formally NSNotificationCenter)
NotificationCenter.default.add(observer: self, name: "NotificationName") {
print("Notification received")
}
继续阅读以了解更多!
安装
CocoaPods
将以下内容添加到您的Podfile
pod 'Actions'
然后运行$ pod install
。
然后在需要使用Actions的类中
import Actions
如果您尚未安装或集成CocoaPods到项目中,您可以在此学习如何做到这一点此处。
Carthage
将以下内容添加到您的Cartfile
github “ManueGE/Actions”
然后运行$ carthage update
。
如果您需要更多关于Cartage的信息,您可以在此处找到
用法
支持类
☝️
UIView 您可以使您的UIViews
响应用户的简单触摸。允许的手势是枚举Gestures
的成员,其值如下:
tap
:单指轻触,接收一个表示所需触摸次数的Int
参数。swipe
:单指滑动,接收一个表示滑动方向的UISwipeGestureRecognizer.Direction
参数。multiTap
:任意数量手指的轻触,接收两个表示所需手指和触摸次数的Int
参数。multiSwipe
:任意数量手指的滑动;接受一个表示滑动方向的UISwipeGestureRecognizer.Direction
参数以及一个表示所需手指和触摸次数的Int
参数。
要将这些手势之一添加到UIView
中,您可以这样做:
let view = UIView()
// Not any gesture argument means .tap(1):
view.addAction {
print("view tapped")
}
// You can also make the closure have one argument (the own view):
view.addAction { (view: UIView) in
print("view \(view) tapped")
}
// Add 3 tap gesture
view.add(gesture: .tap(3)) {
print("View tapped 3 times")
}
// Add a multi swipe gesture with the view as closure argument
view.add(gesture: .multiSwipe(direction: .Left, fingers: 2)) { (view: UIView) in
print("View \(view) swipped left with 2 fingers")
}
所有添加方法返回视图添加的UIGestureRecognizer,以防您需要它。
☝️
UIControl 为您的UIControl
事件分配动作。
您可以添加以下三种类型的闭包:
- 没有任何参数
- 带有一个参数,该参数将是控件本身。
- 带有两个参数,第一个参数将是控件本身,第二个参数将是
UIEvent?
。
您可以添加动作
- 到一个单个的
UIControl.Event
,通过使用方法add(event: UIControl.Event, action: () -> Void)
。 - 同时添加多个控制事件:
add(events: [UIControl.Event], action: ()) -> Void)
这里有一些示例
// Closure without arguments and single event
button.add(event: .touchUpInside) {
print("button tapped")
}
// Closure with one argument and multiple events
textField.add(events: [.editingChanged, .editingDidEnd]) { (textField: UITextField) in
print("Text did change: \(textField.text)")
}
// Closure with two arguments
button.add(event: .touchUpInside) { (sender, event) in
print("Sender: \(sender), Event: \(event)")
}
使用此方法添加的动作可以通过以下方法删除:
func removeActions(for events: UIControl.Event)
注意:只有使用
Actions
方法添加的动作会被删除!
节流
Actions
允许 UIControl
在特定时间间隔之后调用操作,并防止在该间隔内多次调用。换句话说,如果操作在时间间隔过期之前再次被安排,它会取消之前的调用(如果有),防止操作被多次调用。
一个典型的例子是 UITextField
,每次用户输入一些文本时都会触发搜索。如果这个搜索涉及 HTTP 请求,那么每次用户输入一个字符就发送请求可能会导致服务器过载。通过使用 throttle
,您可以等待几毫秒以检查用户是否仍在输入,并且只有在用户在一段时间内没有输入任何字符时才发送操作。
您可以使用此方法使用节流:
textField.throttle(.editingChanged, interval: 0.5) { [unowned self] (textField: UITextField) in
self.performSearch(with: textField.text)
}
除了 UIControl
扩展之外,Throttle
类还可以独立使用,以便在整个应用程序中添加自定义节流。
☝️
UIGestureRecognizer 使用闭包而不是一对目标/动作来创建 UIGestureRecognizer
// without argument
let recognizer = UIRotationGestureRecognizer {
print("Gesture triggered")
}
// with argument
let recognizer = UIRotationGestureRecognizer { (recognizer: UIRotationGestureRecognizer) in
print("Gesture \(recognizer) triggered")
}
☝️
UIBarButtonItem 使用闭包而不是一对目标/动作创建 UIBarButtonItem
。您还可以通过其标题、图像或使用系统类型来创建工具栏项。
let imageTitle = UIBarButtonItem(image: UIImage(named: "image")!) {
print("image item pressed")
}
let titleItem = UIBarButtonItem(title: "Title") {
print("title item pressed")
}
let systemItem = UIBarButtonItem(barButtonSystemItem: .action) {
print("system item pressed")
}
所有这些方法都有一些额外的、可选的参数。它们还可以与接受 UIBarButtonItem
作为参数的闭包一起使用,例如
let imageTitle = UIBarButtonItem(image: UIImage(named: "image")!) { (item: UIBarButtonItem) in
print("image item \(item) pressed")
}
☝️
Timer 用闭包代替目标/动作对创建一个 Timer
。您可以以三种不同方式创建计时器
// Scheduele a timer
Timer.scheduledTimer(timeInterval: 5) {
print("timer fired")
}
// create a timer with a fire date
let timer = Timer(fire: date, interval: 0.5, repeats: true) {
print("timer fired")
}
// create a timer with a time interval
let timer = Timer(timeInterval: 0.5) {
print("timer fired")
}
这些方法都有一些额外的可选参数,如 repeats
和 userInfo
。它们还可以与接受 Timer
作为参数的闭包一起使用,例如
let timer = Timer(fire: date, interval: 0.5, repeats: true) { (timer: Timer) in
print("timer fired \(timer)")
}
☝️
NotificationCenter 使用闭包而不是观察者/选择器对将观察者添加到 NotificationCenter
。您可以通过两种方式完成此操作,一种是会一直存在直到手动停止的观察,另一种是与对象的生存周期绑定的通知
let center = NotificationCenter.default
// This observation will live forever until it is stopped manually
let action = center.observe(notificationName) {
print("Notification received")
}
// Stop observing the notification
center.stopObserving(action: action)
// This observation will live until the observer is deallocated
center.add(observer: self, name: notificationName) { [unowned self] in
print("observe notification from \(self)")
}
// It can be stopped manually by doing:
center.stopObserver(self) // name and object are optional paramteres for this method
这些方法还有一些额外的可选参数 object
:观察者想要接收通知的对象。
Contact
Manuel García-Estañ Martínez
@manueGE
License
动作可在MIT许可证下使用。