Ios UITable查看所有注册的类/NIB
如何查看已注册的类和/或NIB及其单元标识符Ios UITable查看所有注册的类/NIB,ios,uitableview,Ios,Uitableview,如何查看已注册的类和/或NIB及其单元标识符 我想看看哪些已在xib中自动注册(如果是这样做的话),但能够看到任何手动注册的也很好。UITableView将有关已注册的单元格类和NIB的信息存储在单独的字典中,您可以使用KVC和私有属性密钥获取这些信息: NSDictionary *registeredCellClasses = [tableView valueForKey:@"_cellClassDict"]; NSDictionary *registeredNibs = [tableView
我想看看哪些已在xib中自动注册(如果是这样做的话),但能够看到任何手动注册的也很好。UITableView将有关已注册的单元格类和NIB的信息存储在单独的字典中,您可以使用KVC和私有属性密钥获取这些信息:
NSDictionary *registeredCellClasses = [tableView valueForKey:@"_cellClassDict"];
NSDictionary *registeredNibs = [tableView valueForKey:@"_nibMap"];
每个字典将注册的单元重用标识符存储为键,将类名/Nib对象存储为值。Swift
let registeredCellClasses = tableView.value(forKey: "_cellClassDict") as? [String:Any]
let registeredNibs = tableView.value(forKey: "_nibMap") as? [String:UINib]
细节
- 代码12.3(12C33)
- Swift 5.3
\u nibMap
和\u cellClassDict
可能不安全。苹果还没有直接的API来获取注册的细胞。因此,基于\u nibMap
和\u cellClassDict
的解决方案看起来像黑客。我们无法预测,苹果是否会改变这个API。我建议自己制作TableView
,并在那里实现存储逻辑
解决方案
你打算怎么处理这些信息?只是为了兴趣/调试吗?@Wain只是为了调试。当我在验证我的故事板设置是否正确方面遇到问题时,我需要这个。如果你想测试某个单元格是否在某个表视图中注册,它也可以用于单元测试。对collectionview有什么想法吗?@MichaelOzeryansky:我想他只是想展示另一种方法。我知道这是一种更适合生产的解决方案,但最初我只是为了调试。你有一个有趣的模板。
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 ?? [:]
}
}
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()
}
}