TableView 不符合协议
Posted
技术标签:
【中文标题】TableView 不符合协议【英文标题】:TableView not conforming to protocol 【发布时间】:2018-11-03 06:22:15 【问题描述】:我已经建立了一个基本的 CellAssociation 协议。
但是,我添加到协议中的任何内容都会得到:
"Type 'FooTableView' does not conform to protocol 'Cell Association'"
Xcode 似乎给了我一些提示:
"Multiple maching functions named 'register(cellClass:forCellReuseIdentifier:)' with type '(AnyClass?, String) -> ()' (aka '(Optional<AnyObject.Type>, String) -> ()')"
和..
"Rename to 'register(cellClass:forCellReuseIdentifier:)' to satisfy this requirement"
但是,看起来我的注册函数就是这样命名的。
这是 CellAssociation (TableView.swift)
import UIKit
protocol CellAssociation
associatedtype Cell: UITableViewCell
func register()
func register(cellClass: AnyClass?, forCellReuseIdentifier: String)
func dequeueReusableCell(for: IndexPath) -> Cell
func dequeueReusableCell(withIdentifier: String, for: IndexPath) -> UITableViewCell
extension CellAssociation
func register()
register(cellClass: Cell.self, forCellReuseIdentifier: String(describing: Cell.self))
func dequeueReusableCell(for indexPath: IndexPath) -> Cell
return dequeueReusableCell(withIdentifier: String(describing: Cell.self), for: indexPath) as! Cell
这是一个试图符合协议的 TableView:
import UIKit
class LineupDraftSortMenuTableView: UITableView, CellAssociation
typealias Cell = LineupDraftSortMenuCell
init()
super.init(frame: CGRect.zero, style: .plain)
setup()
required convenience init?(coder: NSCoder)
self.init()
func setup()
rowHeight = 40
separatorStyle = .none
backgroundColor = UIColor.clear
register()
这个类会抛出错误:
"Type 'LineupDraftSortMenuTableView' does not conform to protocol 'CellAssociation'"
和 LineupDraftSortMenuCell
import UIKit
class LineupDraftSortMenuCell: UITableViewCell
let optionLabel = DraftboardLabel()
let iconCheck = UIImageView()
let borderView = UIView()
var selectedOption: Bool = false didSet toggleIconCheck()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
required convenience init?(coder: NSCoder)
self.init()
func setup()
addSubviews()
setupSubviews()
addConstraints()
func addSubviews()
contentView.addSubview(optionLabel)
contentView.addSubview(iconCheck)
contentView.addSubview(borderView)
func setupSubviews()
backgroundColor = UIColor.clear
contentView.backgroundColor = UIColor.clear
selectionStyle = .none
optionLabel.font = UIFont.openSans(weight: .Semibold, size: 9)
optionLabel.textColor = UIColor.white
optionLabel.letterSpacing = 0.5
iconCheck.image = UIImage(named: "icon-check")
iconCheck.contentMode = .scaleAspectFit
iconCheck.isHidden = !selectedOption
borderView.backgroundColor = UIColor(0x5c656f)
func addConstraints()
let viewConstraints: [NSLayoutConstraint] = [
optionLabel.leftRancor.constraintEqualToRancor(rancor: contentView.leftRancor, constant: 20),
optionLabel.centerYRancor.constraintEqualToRancor(rancor: contentView.centerYRancor),
iconCheck.widthRancor.constraintEqualToConstant(constant: 12),
iconCheck.heightRancor.constraintEqualToConstant(constant: 10),
iconCheck.centerYRancor.constraintEqualToRancor(rancor: contentView.centerYRancor),
iconCheck.rightRancor.constraintEqualToRancor(rancor: contentView.rightRancor, constant: -20),
borderView.leftRancor.constraintEqualToRancor(rancor: contentView.leftRancor, constant: 10),
borderView.rightRancor.constraintEqualToRancor(rancor: contentView.rightRancor, constant: -10),
borderView.bottomRancor.constraintEqualToRancor(rancor: contentView.bottomRancor),
borderView.heightRancor.constraintEqualToConstant(constant: 1),
]
optionLabel.translatesAutoresizingMaskIntoConstraints = false
iconCheck.translatesAutoresizingMaskIntoConstraints = false
borderView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(viewConstraints)
func toggleIconCheck()
iconCheck.isHidden = !selectedOption
【问题讨论】:
什么是LineupDraftSortMenuCell
?
我在帖子中添加了类定义,希望对您有所帮助!
检查答案:D
【参考方案1】:
您的协议有这个要求:
protocol CellAssociation
func register(cellClass: AnyClass?, forCellReuseIdentifier: String)
但是您的表格视图子类 LineupDraftSortMenuTableView 从未实现该方法。所以不符合协议。
也许您假设该函数声明与 UITableView 已经实现的某些内容相匹配,因此 UITableView 子类可以符合您的协议而无需显式实现它。但事实并非如此。 UITableView 已有的方法是:
func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String)
下划线有很大的不同!
因此,如果您重写协议及其扩展以匹配 UITableView 已经实现的内容,您的代码将编译,如下所示:
protocol CellAssociation
associatedtype Cell: UITableViewCell
func register()
func register(_ cellClass: AnyClass?, forCellReuseIdentifier: String)
func dequeueReusableCell(for: IndexPath) -> Cell
func dequeueReusableCell(withIdentifier: String, for: IndexPath) -> UITableViewCell
extension CellAssociation
func register()
register(Cell.self, forCellReuseIdentifier: String(describing: Cell.self))
func dequeueReusableCell(for indexPath: IndexPath) -> Cell
return dequeueReusableCell(withIdentifier: String(describing: Cell.self), for: indexPath) as! Cell
一旦你这么说了,就可以说:
class LineupDraftSortMenuTableView: UITableView, CellAssociation
// ...
【讨论】:
对dequeueReusableCell
的小更新,在签名中添加indexPath
作为func dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell
【参考方案2】:
其实最近我也差不多碰到了你的问题,你可以参考一下(Swift: Conforming to protocols using default values)。
因此,参考该参考,这是您的代码的修改版本。
protocol CellAssociation
associatedtype Cell: UITableViewCell
func register(cellClass: AnyClass?, forCellReuseIdentifier: String)
func dequeueReusableCell(withIdentifier: String, forIndexPath indexPath: IndexPath) -> UITableViewCell
extension CellAssociation
func register(cellClass: AnyClass? = Cell.self, forCellReuseIdentifier: String = String(describing: Cell.self))
return register(cellClass: cellClass, forCellReuseIdentifier: forCellReuseIdentifier)
func dequeueReusableCell(withIdentifier: String = String(describing: Cell.self), forIndexPath indexPath: IndexPath) -> UITableViewCell
return dequeueReusableCell(withIdentifier: withIdentifier, forIndexPath: indexPath)
我所做的是,我已经传递了默认值,因为您已经为它创建了一个不同的方法,这在 extension
中得到了确认。现在,它将确认protocol
。如果您还有任何疑问或问题,请告诉我。
【讨论】:
如何调用 dequeueResusableCell(withIdentifier:for indexPath:) 使用 withIdentifier 的默认值但仍输入 indexPath 的值? 还没有,我们将不胜感激!以上是关于TableView 不符合协议的主要内容,如果未能解决你的问题,请参考以下文章