Swift中的代表示例

时间:2016-11-09 07:19:23

标签: swift design-patterns delegates protocols delegation

我一直在努力学习如何使用协议进行委派。我理解了所有内容,但除了使用表视图和可能的滚动视图之外,我无法想到何时使用委托。

一般情况下,何时使用授权?

4 个答案:

答案 0 :(得分:60)

什么是代表团?

首先,您应该知道Delegation Pattern不是iOS世界独有的:

  

在软件工程中,委托模式是一种设计模式   面向对象的编程,允许对象组合实现   与继承相同的代码重用。

但是使用delegation in the iOS world是如此常见,我假设您可以看到许多类提供委托/数据源,以便能够为使用过的实例提供属性或行为。它是CocoaTouch中对象如何相互通信的主要机制之一。

备选方案:

但是,委托是允许对象在iOS中相互通信的唯一方法,您可能想知道有:

备注 :如果您有兴趣比较它们,可能需要查看以下文章:

何时使用委托?

所以,问题是:“那么我为什么要使用委托代替那些选项?”

我会尽量简单;当您在两个对象之间存在 一对一 关系时,我建议使用委派。只是为了更清楚,目标谈论 NotificationCenter 是在使用代理时试图理解:

NotificationCenter 代表 一对多 关系;简单来说,它的作用如下:发布(通知)关于特定事件的通知以及观察(获得通知)此通知 - 可以在任何地方观察 / em> else;从逻辑上讲,这就是一对多关系意味着什么。它代表Observer Pattern

如何申请代表团?

为了简化,我会将其作为步骤提及:

  1. 了解要求:每个代理都有自己的规则,列在委托协议中,这是一组方法签名您应该实施以符合此授权。

  2. 遵守代表团:只需将您的班级作为代理人,通过标记即可。例如:class ViewController: UIViewController, UITableViewDelegate {}

  3. 连接委托对象:将您的类标记为委托是,您需要确保要通过确认的对象你的班级为你的班级提供所需的工作。

  4. 实施要求:最后,您的班级必须实施委托协议中列出的所有必需方法。

  5. 例如

    听起来有点令人困惑吗?那个真实世界的例子呢?

    考虑以下情况:

    想象一下,您正在构建与播放音频相关的应用程序。某些viewControllers应该具有音频播放器的视图。在最简单的情况下,我们假设它应该有一个播放/暂停按钮和另一个按钮,比方说,以某种方式显示播放列表,无论它看起来如何。

    到目前为止,音频播放器视图有其分开的UIView类和.xib文件;它应该作为子视图添加到任何所需的viewController中。

    现在,如何为每个viewController的两个按钮添加功能?您可能会想:“简单地说,我会在视图类中添加一个IBAction而且就是这样”,初看起来,它可能听起来不错,但在重新思考一下后,您会发现它不会如果您试图处理在控制器层点击按钮的事件,则适用;为了清楚说明,如果每个viewController在点击音频播放器视图中的按钮时实现了不同的功能,该怎么办?例如:点击“A”中的播放列表viewController将显示一个tableView,但在“B”viewController中点击它将显示一个选择器。

    好吧,让我们将代表团应用于此问题:

    “#”注释表示“如何应用委派?”的步骤部分。

    音频播放器查看:

    // # 1: here is the protocol for creating the delegation
    protocol AudioPlayerDelegate: class {
        func playPauseDidTap()
        func playlistDidTap()
    }
    
    class AudioPlayerView: UIView {
        //MARK:- IBOutlets
        @IBOutlet weak private var btnPlayPause: UIButton!
        @IBOutlet weak private var btnPlaylist: UIButton!
    
        // MARK:- Delegate
        weak 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!!")
        }
    }
    


    快速提示:

    在视图控制器之间使用委派的大多数流行示例之一是Passing Data Back

答案 1 :(得分:5)

当您想要将某些信息或对象A的状态传递给另一个对象时,使用委托B.通常,对象B是创建对象A的对象。

我将列出一些您将使用委托的情况。

  1. 是的,你是对的。表视图和滚动视图使用委托,因为他们想要告诉任何感兴趣的人(通常是你的视图控制器)“有人选择了一行!”或者“有人滚动滚动视图!”。滚动视图和表视图不仅使用委托UITextFieldUIDatePicker,而且许多其他视图也使用委托!

  2. 视图控制器也有代理。例如,UIImagePickerController。原因与上述大致相同 - 因为UIImagePickerController想要告诉您“已选择图像!”等消息。另一个例子是UIPopoverControllerDelegate。这个代表告诉你“popover已被解雇!”

  3. 使用委托的其他类包括CLLocationManager。该代表会告诉您“已检测到用户位置”或“未能检测到用户位置”等内容。

  4. 当您的某个视图控制器想要将消息发送到其他视图控制器时,您可以在代码中使用委托。如果是设置视图控制器,它可能会发送“字体大小设置已更改!”等消息。关注字体大小设置更改的视图控制器将知道并更改标签或其他内容的字体大小。

答案 2 :(得分:3)

将选择方法委托给选择图像

创建baseClass并插入以下代码

enter image description here

创建另一个类,然后插入代码

enter image description here

enter image description here

答案 3 :(得分:1)

IOS世界的代表团,主要是MVC(模型视图控制器) View是一种与Controller通信的方式,它被称为“盲目通信” 和委托意味着给另一个对象(并不关心谁接管,但通常是控制器)的“领导棒”来控制视图无法控制的组件(记住它只是一个视图)或者没有不拥有 使它更简单....
控制器可以与视图通信,但视图无法在没有委托

的情况下与控制器通信