【问题标题】:How to create generic UITableviewCell which have a way to pass the generic datatype to the main UIViewController via delegates or some other way?如何创建通用 UITableviewCell ,它可以通过委托或其他方式将通用数据类型传递给主 UIViewController?
【发布时间】:2019-03-12 09:10:10
【问题描述】:

我正在尝试创建一个通用 UITableViewcell,它可以在创建单元格时将通用类型推断为具体类型,如下所示:

    protocol ConfigureCell {
        associatedtype DataType
        func configure(data:DataType)
    }

            class AbstractCell<T:Codable>: UITableViewCell , ConfigureCell  {

            func configure(data: T) {

            }

            var delegate : AbstractCellDelegate!
        }


class UserCell:AbstractCell<UserDetail> {

    override func configure(data: UserDetail) {

    }
}

    protocol AbstractCellDelegate {
     associatedtype DataType
    func cellBtnClicked(model:DataType,index:Int,cell:AbstractCell<DataType>)
    func cellBtnClicked(model:DataType,index:Int,cell:AbstractCell<DataType>,action:String)
    func cellBtnClicked(model:DataType?,index:Int,cell:AbstractCell<DataType>,action:String)
}

如果需要,我还有一些委托可以用来将相关数据传递给主 UIViewController。如果单元格不是通用的,则代表工作正常,但在创建通用单元格后,我无法使用代理方法并出现以下错误。这可以通过类型擦除来解决,但这将是矫枉过正,因为我不太了解它们。有没有办法我可以创建一个通用单元格,也可以通过委托或任何其他方式调用主 UIViewcontroller 类的方法。

【问题讨论】:

    标签: swift iphone uitableview generics delegates


    【解决方案1】:

    试试这个,信用Swift Associated Type Design Patterns

    protocol ConfigureCell {
        associatedtype DataType
        func configure(data: DataType)
    }
    
    class AbstractCell<T: Codable>: UITableViewCell, ConfigureCell {
        func configure(data: T) {
        }
    
        var delegate: AbstractCellDelegate?
    }
    
    class UserCell: AbstractCell<UserDetail> {
        override func configure(data: UserDetail) {
        }
    }
    
    protocol AbstractCellDelegate {
        func cellBtnClicked(model: Codable, index: Int, cell: Any)
        func cellBtnClicked(model: Codable, index: Int, cell: Any, action: String)
        func cellBtnClicked(model: Codable?, index: Int, cell: Any, action: String)
    }
    
    extension AbstractCellDelegate {
        // dont need them
        func cellBtnClicked(model: Codable, index: Int, cell: Any) {}
        func cellBtnClicked(model: Codable, index: Int, cell: Any, action: String) {}
        func cellBtnClicked(model: Codable?, index: Int, cell: Any, action: String) {}
    }
    
    protocol CellDelegate: AbstractCellDelegate {
        associatedtype DataType: Codable
        func cellBtnClicked(model: DataType, index: Int, cell: AbstractCell<DataType>)
        func cellBtnClicked(model: DataType, index: Int, cell: AbstractCell<DataType>, action: String)
        func cellBtnClicked(model: DataType?, index: Int, cell: AbstractCell<DataType>, action: String)
    }
    
    struct UserDetail: Codable {
    }
    
    struct MyDataType: Codable {
    }
    
    class MyViewController: CellDelegate {
        func cellBtnClicked(model: MyDataType, index: Int, cell: AbstractCell<MyDataType>) {
        }
    
        func cellBtnClicked(model: MyDataType, index: Int, cell: AbstractCell<MyDataType>, action: String) {
        }
    
        func cellBtnClicked(model: MyDataType?, index: Int, cell: AbstractCell<MyDataType>, action: String) {
        }
    
        typealias DataType = MyDataType
    }
    
    

    编辑 你可以试试这个

    protocol ConfigureCell {
        associatedtype DataType
        func configure(model: DataType)
    }
    
    protocol DelegateCell {
        associatedtype DataType
        func btnTap(model: DataType)
    }
    
    class UserCell: ConfigureCell, DelegateCell {
        typealias DataType = UserDetail
    
        var btnTapHandler: ((DataType) -> Void)?
    
        func btnTap(model: DataType) {
            btnTapHandler?(model)
        }
    
        var model: DataType?
        func configure(model: DataType) {
            self.model = model
        }
    
        @IBAction func tap() {
            if let model = model {
                btnTap(model: model)
            }
        }
    }
    
    struct UserDetail {
        var name = "Manas"
    }
    
    class TableViewController {
    
        var items = [UserDetail]()
    
        func cellForIndexPath(row: Int) {
            let cell = UserCell()
            cell.configure(model: items[row])
            cell.btnTapHandler = { data in
                print(data.name)
            }
        }
    
    }
    

    【讨论】:

    • 您好 chandOnly23 ,感谢您的建议,但问题仍然存在。要使用 celldelegate,我需要在调用方法的某个类中声明它,但是每当我尝试声明 celldelegate 时,它​​都会显示错误:“协议‘CellDelegate’只能用作通用约束,因为它具有 Self 或相关类型要求”
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多