如何查看已注册的类和/或nib及其单元标识符?
我想看看哪些已经在xib中自动注册(如果它是如何完成的),但是也可以看到任何手动注册也会很棒。
答案 0 :(得分:13)
UITableView将有关已注册单元格类和nib的信息存储在单独的词典中,您可以使用KVC和私有属性键获取这些词典:
NSDictionary *registeredCellClasses = [tableView valueForKey:@"_cellClassDict"];
NSDictionary *registeredNibs = [tableView valueForKey:@"_nibMap"];
每个字典将注册的单元格重用标识符存储为键,将类名称/ Nib对象存储为值。
答案 1 :(得分:5)
<强>夫特强>
let registeredCellClasses = tableView.value(forKey: "_cellClassDict") as? [String:Any]
let registeredNibs = tableView.value(forKey: "_nibMap") as? [String:UINib]
答案 2 :(得分:3)
extension UITableView {
var registeredNibs: [String: UINib] {
let dict = value(forKey: "_nibMap") as? [String: UINib]
return dict ?? [:]
}
var registeredClasses: [String: Any] {
let dict = value(forKey: "_cellClassDict") as? [String: Any]
return dict ?? [:]
}
}
答案 3 :(得分:0)
使用 _nibMap
和 _cellClassDict
可能不安全。 Apple 没有直接的 API 来获取注册单元。因此,基于 _nibMap
和 _cellClassDict
的解决方案看起来像黑客。而且我们无法预测,Apple 是否会更改此 API。我建议自己制作 TableView
并在那里实现存储逻辑。
class TableView: UITableView {
private (set) lazy var registeredCellIdentifiers = Set<String>()
func register(nib: UINib?, forCellReuseIdentifier identifier: String) {
super.register(nib, forCellReuseIdentifier: identifier)
registeredCellIdentifiers.insert(identifier)
}
func register(nib: UINib?, forHeaderFooterViewReuseIdentifier identifier: String) {
super.register(nib, forHeaderFooterViewReuseIdentifier: identifier)
registeredCellIdentifiers.insert(identifier)
}
func register(cellClass: AnyClass?, forCellReuseIdentifier identifier: String) {
super.register(cellClass, forCellReuseIdentifier: identifier)
registeredCellIdentifiers.insert(identifier)
}
func register(aClass: AnyClass?, forHeaderFooterViewReuseIdentifier identifier: String) {
super.register(aClass, forHeaderFooterViewReuseIdentifier: identifier)
registeredCellIdentifiers.insert(identifier)
}
@available(*, deprecated, message: "use register(nib: UINib?, forCellReuseIdentifier identifier: String) instead")
override func register(_ nib: UINib?, forCellReuseIdentifier identifier: String) {}
@available(*, deprecated, message: "use register(nib: UINib?, forCellReuseIdentifier identifier: String) instead")
override func register(_ nib: UINib?, forCellReuseIdentifier identifier: String) {}
@available(*, deprecated, message: "use register(nib: UINib?, forHeaderFooterViewReuseIdentifier identifier: String) instead")
override func register(_ nib: UINib?, forHeaderFooterViewReuseIdentifier identifier: String) { }
@available(*, deprecated, message: "ude register(cellClass: AnyClass?, forCellReuseIdentifier identifier: String) instead")
override func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String) {}
@available(*, deprecated, message: "use register(aClass: AnyClass?, forHeaderFooterViewReuseIdentifier identifier: String) instead")
override func register(_ aClass: AnyClass?, forHeaderFooterViewReuseIdentifier identifier: String) {}
}
不要忘记在此处粘贴上面定义的代码
// MARK: - Auto Generated identifiers
protocol Identifiable: class {
static var identifier: String { get }
}
extension Identifiable {
static var identifier: String { "\(self)" }
}
// MARK: - Define Cells
class TableViewCell: UITableViewCell, Identifiable {
var mainBackgroundColor: UIColor { .white }
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = mainBackgroundColor
}
@available(*, deprecated, message: "")
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
class GreenCell: TableViewCell {
override var mainBackgroundColor: UIColor { .green }
}
class OrangeCell: TableViewCell {
override var mainBackgroundColor: UIColor { .orange }
}
// MARK: ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let tableView = TableView()
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
tableView.register(cellClass: GreenCell.self, forCellReuseIdentifier: GreenCell.identifier)
tableView.register(cellClass: OrangeCell.self, forCellReuseIdentifier: OrangeCell.identifier)
tableView.dataSource = self
print(tableView.registeredCellIdentifiers)
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int { 1 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 10 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = (indexPath.row % 2) == 0 ? GreenCell.identifier : OrangeCell.identifier
return tableView.dequeueReusableCell(withIdentifier: identifier) ?? UITableViewCell()
}
}