如何将协议采用仅限于UIViewController?

时间:2018-08-10 13:01:11

标签: uiviewcontroller swift-protocols

因此,我将viewControllers嵌入viewControllers中以构建复杂的tableView(请参阅Dave Delong Better MVC文章https://davedelong.com/blog/2017/11/06/a-better-mvc-part-1-the-problems/)。我所有的tableView单元都是遵循以下CellVC协议的ViewController,并且它们在加载时作为子视图添加到UITableViewCell的contentView中。

此方法的优点是可以将单元的所有逻辑封装在嵌入式viewController中。具体来说,当选择单元格(didSelect),显示附件类型等时该怎么做。

如何让编译器知道如果对象采用CellVC,则它必须是UIViewController,这样我就不必将CellVC转换为UIViewController?

此协议因“ EXE_BAD_ACESS”而崩溃

import UIKit

protocol CellVC where Self: UIViewController {

    var showDisclosureIcon: Bool { get }
    func activateTF()
    func didSelect()
}

此版本的协议有效,但没有告诉编译器,因为符合CellVC的类型是UIViewController。

protocol CellVC { 
    var showsDisclosureIcon: Bool { get }
    func activateTF()
    func didSelect()
}

实现-一个作为ViewController的“单元”之一的示例。

import UIKit
import CoreData

class ScheduleCell: UIViewController, CellVC {

    //MARK: - Factory
    static func create(context: NSManagedObjectContext) -> ScheduleCell {
        let sB = UIStoryboard(name: "ScheduleCell", bundle: nil)
        guard let cell = sB.instantiateViewController(withIdentifier: "ScheduleCell") as? ScheduleCell else {
            fatalError("cell load failed")}
        cell.context = context
        return cell
    }

    //MARK: - Properties
    var context: NSManagedObjectContext!
    @IBOutlet var label: UILabel!
    @IBOutlet var detailLabel: UILabel!
    @IBOutlet var checkboxContainer: UIView!

    //MARK: - CellVC
    var showDisclosureIcon: Bool = true

    func activateTF() { return }  //No Text to Activate

    func didSelect() {
        let vc = UIViewController()
        vc.view.backgroundColor = .purple
        self.navigationController?.pushViewController(vc, animated: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupLabels()
    }

    func setupLabels() {
        label.text = "Schedule"
        detailLabel.text = "Dunno"
    }
}

消费-在这里您可以看到不受欢迎的向下转换“ cellVC as!UIViewController”和最后一行“ if cellVC.showsDisclosureIcon {...}”崩溃并显示为“ EXC_BAD_ACCESS”,这使我想到了编写协议的方式是错误的。

func configureCell(_ cell: UITableViewCell, at indexPath: IndexPath) {
    let cellVC = data.cellVCForRowAt(indexPath: indexPath)
    self.embed(viewController: cellVC as! UIViewController, inContainerView: cell.contentView)
    if cellVC.showDisclosureIcon {
        cell.accessoryType = .disclosureIndicator
    }
}

0 个答案:

没有答案