前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过 XIB 自定义 View 的便捷加载方法

通过 XIB 自定义 View 的便捷加载方法

作者头像
韦弦zhy
发布2021-11-24 14:07:41
9920
发布2021-11-24 14:07:41
举报
文章被收录于专栏:韦弦的偶尔分享

虽然 XIB 实现 View 有各种各样的缺点,但是不可否认我们仍然在项目中或多或少的有使用。在加载 XIB 视图的时候每个人都会有自己的封装,今天我从最原始加载方式开始,分享一下我的便捷加载方式是怎么写出来的。

加载通过 XIB 自定义 View 的加载我们一般会有如下方法

XIBView: ZYXIBTestView.xib

在需要使用的 VC:

代码语言:javascript
复制
override func viewDidLoad() {
    super.viewDidLoad()
    let view = Bundle.main.loadNibNamed("ZYXIBTestView", owner: nil, options: [:])?.last as! ZYXIBTestView
}

或者在XIB对应的view: ZYXIBTestView.swift

代码语言:javascript
复制
class func initByNib() -> ZYXIBTestView {
        return  Bundle.main.loadNibNamed("ZYXIBTestView", owner: nil, options: [:])?.last as! ZYXIBTestView
}

使用的时候:
override func viewDidLoad() {
    super.viewDidLoad()
    let view = ZYXIBTestView.initByNib()
}

后面我参考我原来写的一个UITableViewCell 的扩展:

代码语言:javascript
复制
extension UITableView {
         /// 注册 xib cell
    func register<T: UITableViewCell>(nib cellType: T.Type) {
        register(UINib(nibName: String(describing: cellType), bundle: nil), forCellReuseIdentifier: String(describing: cellType))
    }

    /// 复用代码 xib
    func dequeueReusable<T: UITableViewCell>(_ cellType: T.Type = T.self, for indexPath: IndexPath) -> T {
        guard let cell = dequeueReusableCell(withIdentifier: String(describing: cellType), for: indexPath) as? T else {
            fatalError(
                "Failed to dequeue a cell with identifier \(String(describing: cellType)) matching type \(cellType.self). "
                    + "Check that the reuseIdentifier is set properly in your XIB/Storyboard "
                    + "and that you registered the cell beforehand"
            )
        }
        return cell
    }
}

写了如下UIView 的扩展:

代码语言:javascript
复制
extension UIView {
    class func initNib<T: UIView>(by nibType: T.Type) -> T {
        guard let view = Bundle.main.loadNibNamed(String(describing: nibType), owner: nil, options: [:])?.last as? T else {
            fatalError(
                "Failed to load a view with nibName \(String(describing: nibType)) "
                    + "Check that the nibName of your XIB/Storyboard "
            )
        }
            return view 
    }
}

这个时候无需再 View 中写任何代码,就可以直接使用:

代码语言:javascript
复制
override func viewDidLoad() {
    super.viewDidLoad()
    let view = ZYXIBTestView.initNib(by: ZYXIBTestView.self)
}

可是看起有点怪怪的,UITableView 复用 Cell 调用是这样的,完全符合使用习惯:

代码语言:javascript
复制
tableView.register(nib: ZTTestCell.self)
···
let cell = tableView.dequeueReusable(ZTTestCell.self, for: indexPath)
···

此时想起了 Self 关键字 可以动态获取引用类型, 所以:

代码语言:javascript
复制
extension UIView {
    /// 加载 xib view 类方法
    @objc class func initByNib() -> Self {
        guard let view = Bundle.main.loadNibNamed(String(describing: Self.self), owner: nil, options: [:])?.last as? Self else {
            fatalError(
                "Failed to load a view with nibName \(String(describing: Self.self)) "
                  + "Check that the nibName of your XIB/Storyboard "
          )
        }
        return view
    }
}

此时使用则更符合预期了:

代码语言:javascript
复制
override func viewDidLoad() {
    super.viewDidLoad()
    let view = ZYXIBTestView.initByNib()
}

同时也支持了OC, 毕竟开始的泛型方法OC是无法调用的:

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *view = [ZYXIBTestView initByNib];
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/10/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档