swift面向協(xié)議編程(POP)之經(jīng)典實例

1、實例說明及實現(xiàn)

使用委托模式實現(xiàn)。
協(xié)議最常見的用法莫過于進(jìn)行代理傳值。常用的場景有:controller中自定義了一個view,view中添加了一個button。點(diǎn)擊自定義中的button去改變在controller上label的值。代碼如下:

自定義ClickView.swift:

//
//  ClickView.swift
//  Demo
//
//  Created by 王樹軍 on 2018/7/30.
//  Copyright ? 2018 王樹軍. All rights reserved.
//

import UIKit

/* 屏幕的寬 */
public let kSCREEN_WIDTH  = UIScreen.main.bounds.size.width
/* 屏幕的高 */
public let kSCREEN_HEIGHT  = UIScreen.main.bounds.size.height

@objc protocol ClickViewDelegate {
    func changeLabel(_ str: String)
}

class ClickView: UIView {

    var keywords: [String]?
    var buttons: [UIButton]?
    
    weak public var delegate: ClickViewDelegate?
    
    init(frame: CGRect, keywords: [String]) {
        super.init(frame: frame)
        self.keywords = keywords
        renderVier()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
    }
    
    private func renderVier() {
        buttons = keywords?.enumerated().map({ (index, key) -> UIButton in
            let buttonWidth = kSCREEN_WIDTH/CGFloat((keywords?.count)!)
            let button = UIButton.init(frame: CGRect.init(x: CGFloat(index)*buttonWidth, y: 0, width: buttonWidth, height: 50))
            button.setTitle(key, for: .normal)
            button.setTitleColor(UIColor.blue, for: .normal)
            button.backgroundColor = UIColor.gray
            button.tag = index
            button.addTarget(self, action: #selector(tapButton(sender:)), for: .touchUpInside)
            addSubview(button)
            return button
            
        })
    }
    
    @objc func tapButton(sender: UIButton) {
        delegate?.changeLabel(keywords![sender.tag])
    }
}

ViewController.swift

//
//  ViewController.swift
//  Demo
//
//  Created by 王樹軍 on 2018/7/30.
//  Copyright ? 2018 王樹軍. All rights reserved.
//

import UIKit

class ViewController: UIViewController ,ClickViewDelegate{
    
    lazy var label: UILabel = {
        var label = UILabel(frame: CGRect.init(x: 50, y: 200, width: 100, height: 30))
        label.text = labelStr
        label.backgroundColor = UIColor.red
        return label
    }()
    
    var labelStr: String? {
        didSet {
            label.text = labelStr
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(label)
        setupClickView()
    }
    
    func setupClickView() {
        let clickView =   ClickView(frame: CGRect.init(x: 0, y: 88, width: kSCREEN_WIDTH, height: 50), keywords: ["aa", "bb"])
        clickView.delegate = self
        view.addSubview(clickView)
    }
    
    func changeLabel(_ str: String) {
        labelStr = str
    }
}


2、注意事項

  • 1、在 ARC 中,對于一般的 delegate,我們會在聲明中將其指定為 weak,在這個 delegate 實際的對象被釋放的時候,會被重置回 nil。

  • 2、 Swift 的 protocol 是可以被除了 class 以外的其他類型遵守的,而對于像 struct 或是 enum 這樣的類型,本身就不通過引用計數(shù)來管理內(nèi)存,所以也不可能用 weak 這樣的 ARC 的概念來進(jìn)行修飾。
    兩種解決方法:
    ①、使用@objc
    ②、聲明類類型專屬協(xié)議。通過添加 class 關(guān)鍵字來限制協(xié)議只能被類類型遵循,
    而結(jié)構(gòu)體或枚舉不能遵循該協(xié)議。class 關(guān)鍵字必須第一個出現(xiàn)在協(xié)議的繼承列表中,在其他繼承的協(xié)議之前
    protocol ClickViewDelegate : class

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,172評論 3 119
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,194評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,621評論 1 32
  • 日念家人一好處,念力加持享幸福!正念,正行,正向,正力! 2017.7.29~30: 《念爸媽好》這兩天剛好要開...
    丁昕家庭教育指導(dǎo)閱讀 1,644評論 0 1
  • 長尾理論研究的是利基市場(縫隙市場)。 一 免費(fèi) 我們的文化合經(jīng)濟(jì)重心正在加速轉(zhuǎn)移,從需求曲線頭部的少數(shù)大熱門(主...
    臥龍小閱讀 641評論 0 1

友情鏈接更多精彩內(nèi)容