美文网首页开发笔记-Swift
让自定义 UITableViewCell 的使用更便捷

让自定义 UITableViewCell 的使用更便捷

作者: 周胖儿 | 来源:发表于2019-08-23 23:39 被阅读0次

    在使用 UITableView 中,一个合乎 Apple 规范的 Cell 注册/使用流程需要至少两部分代码。
    1.注册 Cell

    tableView.register(MyCellClass.self, forCellReuseIdentifier: "CellIdentifier")
    
    1. 在 delegate 中完成 cell 的获取
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier") as! MyCellClass
        return cell
    }
    

    当项目中多处用到 UITableView 时,这样的松耦合的写法很容易犯错,在不慎把 reuseIdentifier 或 MyCellCalss 的类型写错时很难发现错误。为此,做一个如下的扩展也许很有意义:

    // MARK: - 让单元格支持复用的协议。
    public protocol UITableViewCellReusableSupport : class {
        /// 复用标识。
        static var reuseableIdentifier: String { get }
    }
     
    // MARK: - 提供 UITableViewCellReusableSupport 的默认实现。
    public extension UITableViewCellReusableSupport where Self : UITableViewCell {
        /// 复用标识。
        static var reuseableIdentifier: String {
            return String(describing: self)
        }
    }
    
    // MARK: - 扩展 UITableView 的特性。
    public extension UITableView {
    
        /// 注册一个可复用的单元格。
        ///
        /// - Parameter cellClass: 单元格类型。
        func register<T : UITableViewCell >(_ cellClass: T.Type) where T : UITableViewCellReusableSupport {
            self.register(cellClass, forCellReuseIdentifier: T.reuseableIdentifier)
        }
        
        /// 获取一个可复用的单元格。
        ///
        /// - Parameters:
        ///   - cellClass: 单元格类型。
        ///   - indexPath: 单元格位置。
        /// - Returns: 获取的单元格。
        func dequeueReusableCell<T : UITableViewCell>(_ cellClass: T.Type, for indexPath: IndexPath) -> T? where T : UITableViewCellReusableSupport {
            return self.dequeueReusableCell(withIdentifier: T.reuseableIdentifier, for: indexPath) as! T
        }
        
        /// 获取指定位置的单元格。
        ///
        /// - Parameters:
        ///   - cellClass: 单元格类型。
        ///   - indexPath: 单元格位置。
        /// - Returns: 获取的单元格。
        func cellForRow<T : UITableViewCell>(_ cellClass: T.Type, at indexPath: IndexPath ) -> T? where T : UITableViewCellReusableSupport {
            return self.cellForRow(at: indexPath) as? T
        }
    }
    

    搞定后,以后的代码可以这样写:

    // 1. 自定义 UITableViewCell 时支持 UITableViewCellReusableSupport 协议
    class MyTableViewCell: UITableViewCell, UITableViewCellReusableSupport {
    }
    
    // 2. 在 UITableView 中用如下方式注册 Cell
    tableView.register(MyTableViewCell.self)
    
    // 3. 在 delegate 中更精准的获取 Cell
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       // 获取的 cell 是 MyTableViewCell 类型,而不是 UITableViewCell 类型。
       let cell = tableView.dequeueReusableCell(MyTableViewCell.self, for: indexPath)
       return cell
    }
    
    // 4. 在使用 IndexPath 获取 Cell 时这样写
    if let cell = tableView.cellForRow(MyTableViewCell.self, at: newIndexPath) {
       // 获取的 cell 是 MyTableViewCell 类型,而不是 UITableViewCell 类型。
    }
    

    最后,UICollectionView 也可以这样做。

    相关文章

      网友评论

        本文标题:让自定义 UITableViewCell 的使用更便捷

        本文链接:https://www.haomeiwen.com/subject/zxixectx.html