Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 注册并退出特定类型的UITableViewCell_Ios_Swift_Uitableview_Generics - Fatal编程技术网

Ios 注册并退出特定类型的UITableViewCell

Ios 注册并退出特定类型的UITableViewCell,ios,swift,uitableview,generics,Ios,Swift,Uitableview,Generics,UITableView是在objc已经“过时”且从未提及swift时构建的。在objc中,如果您将一个单元格出列以强制转换它,则无需进行任何操作,只要您有正确的单元格,您只需分配它,一切都会正常进行 随着斯威夫特的出现,仿制药的力量进入了iOS(和其他苹果)平台 现在我发现自己一次又一次地写了很多样板文件(定义一个标识符,转换单元格,使用强制展开致命错误…) 因此,我想知道是否有一些想法可以使代码更易于使用和更简洁。解决这个问题的简单方法是编写一个小的扩展 如果未注册的单元格已退出队列,此解决方

UITableView是在objc已经“过时”且从未提及swift时构建的。在objc中,如果您将一个单元格出列以强制转换它,则无需进行任何操作,只要您有正确的单元格,您只需分配它,一切都会正常进行

随着斯威夫特的出现,仿制药的力量进入了iOS(和其他苹果)平台

现在我发现自己一次又一次地写了很多样板文件(定义一个标识符,转换单元格,使用强制展开致命错误…)


因此,我想知道是否有一些想法可以使代码更易于使用和更简洁。

解决这个问题的简单方法是编写一个小的扩展

如果未注册的单元格已退出队列,此解决方案将导致致命错误。如果我们调用
dequeueReusableCell(withIdentifier:for:)
,如果我们没有注册该单元,这已经是iOS的默认行为

为了实现这一点,我们需要一种方法为任何类型的单元创建一个唯一标识符,我们将使用泛型注册和出列这些单元。如果您想让同一个单元格中的不同标识符退出队列,那么您必须退回到默认系统(从来没有这样做的必要)

因此,让我们创建一个名为
UITableView+Tools.swift
(或您想命名的名称)的类


就这样。希望你喜欢这个主意。任何其他(更好或更差的@Saren)您的解决方案对单个
UITableViewCell
都很有效,但我对它做了一些增强,支持多个
UITableViewCell
注册

UITableView+extension.swift

public protocol ClassNameProtocol {
    static var className: String { get }
    var className: String { get }
}

public extension ClassNameProtocol {
    public static var className: String {
        return String(describing: self)
    }

    public var className: String {
        return type(of: self).className
    }
}

extension NSObject: ClassNameProtocol {}


public extension UITableView {
    public func register<T: UITableViewCell>(cellType: T.Type) {
        let className = cellType.className
        let nib = UINib(nibName: className, bundle: nil)
        register(nib, forCellReuseIdentifier: className)
    }

    public func register<T: UITableViewCell>(cellTypes: [T.Type]) {
        cellTypes.forEach { register(cellType: $0) }
    }

    public func dequeueReusableCell<T: UITableViewCell>(with type: T.Type, for indexPath: IndexPath) -> T {
        return self.dequeueReusableCell(withIdentifier: type.className, for: indexPath) as! T
    }

    public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterType: T.Type) {
        let className = HeaderFooterType.className
        let nib = UINib(nibName: className, bundle: nil)
        register(nib, forHeaderFooterViewReuseIdentifier: className)
    }

    public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterTypes: [T.Type]) {
        HeaderFooterTypes.forEach { registerHeaderFooter(HeaderFooterType: $0) }
    }
}
注意:请确保您的
UITableviewCell
的类名和可重用ID应该相同。

func viewDidLoad {
    ...

    tableView.register(MyCustomCell.self)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = dequeueReusableCell(forType: MyCustomCell.self, for: indexPath)
    cell.viewModel = cellModel(for: indexPath)

    return cell
}
public protocol ClassNameProtocol {
    static var className: String { get }
    var className: String { get }
}

public extension ClassNameProtocol {
    public static var className: String {
        return String(describing: self)
    }

    public var className: String {
        return type(of: self).className
    }
}

extension NSObject: ClassNameProtocol {}


public extension UITableView {
    public func register<T: UITableViewCell>(cellType: T.Type) {
        let className = cellType.className
        let nib = UINib(nibName: className, bundle: nil)
        register(nib, forCellReuseIdentifier: className)
    }

    public func register<T: UITableViewCell>(cellTypes: [T.Type]) {
        cellTypes.forEach { register(cellType: $0) }
    }

    public func dequeueReusableCell<T: UITableViewCell>(with type: T.Type, for indexPath: IndexPath) -> T {
        return self.dequeueReusableCell(withIdentifier: type.className, for: indexPath) as! T
    }

    public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterType: T.Type) {
        let className = HeaderFooterType.className
        let nib = UINib(nibName: className, bundle: nil)
        register(nib, forHeaderFooterViewReuseIdentifier: className)
    }

    public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterTypes: [T.Type]) {
        HeaderFooterTypes.forEach { registerHeaderFooter(HeaderFooterType: $0) }
    }
}
fileprivate let arrCells = [ContactTableViewCell.self,ContactDetailsCell.self]
self.register(cellTypes: arrCells)