代表在Swift中的例子
我一直在努力学习如何使用协议委托工作。 我明白了一切,但我不能想到何时使用委托,而不是使用表视图和可能的滚动视图。
一般来说,代表团在什么时候使用?
什么是授权?
首先,你应该知道, 委托模式并非iOS世界的专有:
在软件工程中,委托模式是面向对象编程中的一种devise模式,它允许对象组合实现与inheritance一样的代码重用。
但是,在iOS世界中使用委托是非常常见的,我认为你可以看到许多类提供了一个委托/数据源来提供为所使用的实例提供属性或行为的能力。 它是CocoaTouch中对象如何相互对话的主要机制之一。
备择scheme:
然而,委托并不是让iOS中的对象互相交stream的唯一方式,您可能想知道:
- 通知中心 。
- KVO(键值观测) 。
- 完成处理程序/callback(使用闭包) 。
- 目标行动 。
备注 :如果您有兴趣对它们进行比较,您可能需要查看以下文章:
- 沟通模式。
- 何时在iOS中使用委派,通知或观察。
- 代表与观察员。
何时使用委派?
所以,问题是:“那么我为什么要用代表团而不是这些select?
我会尽量简化。 当你在两个对象之间有一对一的关系时,我会build议使用委托。 为了更清楚一点, 通告中心的目标是在使用代表团的时候有意义:
通知中心代表一对多的关系; 简单地说,它的工作原理是: 发布(通知)特定事件的通知,并观察(通知)此通知 – 可以在其他任何地方观察到; 从逻辑上讲,这就是一对多的关系。 这是观察者模式的表示。
如何申请授权?
为简化起见,我将其作为步骤来提及:
-
了解要求:每个委托都有其自己的规则 ,在委托协议中列出,这是一组方法签名,您应该执行该方法签名以符合此委派。
-
符合代表团:它只是让你的class级成为代表,通过标记。 比如:
class ViewController: UIViewController, UITableViewDelegate {}
。 -
连接委托对象:将你的class级标记为一个委托是不够的,你需要确保你的class级确认这个对象,以便将所需的工作交给class级。
-
实现要求:最后,你的类必须实现在委托协议中列出的所有必需的方法。
例如
这听起来有点混乱吗? 那么现实世界的例子呢?
考虑以下情况:
想象一下,你正在构build一个与播放audio有关的应用程序。 一些viewControllers应该有一个audio播放器的视图。 在最简单的情况下,我们假设它应该有一个播放/暂停button,另一个button,让我们假设播放列表以某种方式显示,不pipe它是怎么样的。
到目前为止,audio播放器视图有其独立的UIView
类和.xib
文件; 它应该添加为任何所需的viewController子视图。
现在,你怎么能为每个viewController的button添加function? 你可能会这样想:“简单地说,我将在视图类中增加一个IBAction
,就是这样”,一开始看,听起来似乎没问题,但是经过一番思考之后,你会意识到,如果你正在尝试处理控制层的button事件; 为了说清楚,如果每个viewController在点击audio播放器视图中的button时实现了不同的function? 例如:点击“A”中的播放列表viewController将显示一个tableView,但在“B”viewController中点击它将显示一个select器。
那么,让我们把这个问题应用到这个问题上:
“#”注释表示“如何应用授权”的步骤。 部分。
audio播放器视图:
// # 1: here is the protocol for creating the delegation protocol AudioPlayerDelegate { func playPauseDidTap() func playlistDidTap() } class AudioPlayerView: UIView { //MARK:- IBOutlets @IBOutlet weak private var btnPlayPause: UIButton! @IBOutlet weak private var btnPlaylist: UIButton! // MARK:- Delegate var delegate:AudioPlayerDelegate? // IBActions @IBAction private func playPauseTapped(_ sender: AnyObject) { delegate?.playPauseDidTap() } @IBAction private func playlistTapped(_ sender: AnyObject) { delegate?.playlistDidTap() } }
视图控制器:
class ViewController: UIViewController { var audioPlayer: AudioPlayerView? // MARK:- Life Cycle override func viewDidLoad() { super.viewDidLoad() audioPlayer = AudioPlayerView() // # 3: the "AudioPlayerView" instance delegate will implemented by my class "ViewController" audioPlayer?.delegate = self } } // # 2: "ViewController" will implement "AudioPlayerDelegate": extension ViewController: AudioPlayerDelegate { // # 4: "ViewController" implements "AudioPlayerDelegate" requirments: func playPauseDidTap() { print("play/pause tapped!!") } func playlistDidTap() { // note that is should do a different behavior in each viewController... print("list tapped!!") } }
快速提示:
作为使用委托最stream行的例子之一是在视图控制器之间传递数据 。
当您想要将对象A的某些信息或状态传递给另一个对象B时,将使用委托。通常,对象B是创build对象A的对象。
我将列举一些您将使用委派的情况。
-
你是对的。 表视图和滚动视图使用委托,因为他们想告诉谁有兴趣(通常你的视图控制器),“有人select了一排!” 或“有人滚动滚动视图!”。 不仅滚动视图和表视图使用委托,
UITextField
和UIDatePicker
和许多其他视图也使用委托! -
视图控制器也有代表。 例如,
UIImagePickerController
。 之所以与上述大致相同,是因为UIImagePickerController
想告诉你像“一个图像已被选中!”的消息。 另一个例子是UIPopoverControllerDelegate
。 这位代表告诉你“罂粟被解雇了! -
其他使用委托的类包括
CLLocationManager
。 这个代表告诉你“用户的位置已被检测到”或者“未能检测到用户的位置”。 -
当您的代码的某个视图控制器想要将消息发送到其他视图控制器时,您可以在代码中使用委托。 如果它是一个设置视图控制器,它可能会发送消息,如“字体大小设置已更改!” 而关心字体大小设置改变的视图控制器会知道和改变标签的字体大小。
在IOS世界里,主要是在MVC(模型视图控制器)中的委派是View与Controller交谈的一种方式,它被称为“盲通信”,委托意味着给另一个对象“谁是接pipe,但通常是控制器)来控制视图无法控制的组件自己(记住它只是一个视图)或不自己使它更简单….
控制器可以与视图进行交谈,但是没有授权,视图不能与控制器交谈