Swift笔记43:UIView和XIB、模版

简单介绍

下面的几种用法第一种不推荐虽然简单但是会增加渲染
推荐二,三,四种,我们通过模版的创建可以一步到位。

查看demo ,UIView和Xib文件夹下

基本用法1: Xib 自定义View实例化
class MyClass: UIView {        
    class func instanceFromNib() -> UIView {
        return UINib(nibName:"nib file name", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as UIView
    }    
}

UIView添加.xib的子视图步骤:
1 创建UIView子类,命名Template。
2 在Interface Builder中创建一个新的.xib文件,并将File's Owner的类设置为Template。
3 在Template类中,通过重写initWithFrame:方法来加载.xib文件,并将其与Template关联起来。
这种做法是在view上面贴一层XIB,有点事简单方便,缺点是多了一层视图。

class Template: UIView {
    var contentView: UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView = loadXib()
        addSubview(contentView)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func loadXib() -> UIView {
        let className = type(of: self)
        let bundle = Bundle(for: className)
        let name = NSStringFromClass(className).components(separatedBy: ".").last
        let nib = UINib(nibName: name!, bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        return view
    }

    override func layoutSubviews() {
        super.layoutSubviews()
    }
}
基本用法2: UIView实例方法创建Bundle和view

UIView通过XIB加载步骤
1 创建UIView子类,命名Template。
2 在Interface Builder中创建一个新的.xib文件,并将File's Owner的类设置为Template。
这一步也可以不做,这里为什么这么做的原因是,为了和我们后面自定义模版保持一致。
3 XIB视图的第四个图标(show the identity insepctor)的custom class填写 Template
4 在Template类中,通过重写override func awakeFromNib()方法来加载.xib文件,并将其与Template关联起来。
5 把view视图的size设置成freedom
6 把view视图的Layout 设置为inferred

class Template: UIView {
    
    /// XIB 读取的时候required init可以不写,写的话就会调用
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    static func loadFromNib(_ nibname: String? = nil, index: Int = 0) -> Self { // Self(大写)当前类对象
        let loadName = nibname == nil ? "\(Self.self)" : nibname!
        return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)![index] as! Self
    }

    override func layoutSubviews() {
        super.layoutSubviews()
    }
}
基本用法3: Bundle扩展方法创建Bundle

在用法2的基础上通过协议扩展
1 创建MyXibView:UIView,MyXibView的xib
2 custom class填写MyXibView
3 Bundle扩展方法创建view
4 实现

extension Bundle {

    static func loadView<T>(fromNib name: String, withType type: T.Type) -> T {
        if let view = Bundle.main.loadNibNamed(name, owner: nil, options: nil)?.first as? T {
            return view
        }

        fatalError("Could not load view with type " + String(describing: type))
    }
}
let myxibView:MyXibView = Bundle.loadView(fromNib: "MyXibView", withType: MyXibView.self)
myxibView.frame = CGRectMake(10, distanceTop+430, kScreenWidth-20, 50)
view.addSubview(myxibView)
基本用法4: UIView协议方法创建Bundle和view

在用法2的基础上通过协议扩展
1 创建MyXibView:UIView,MyXibView的xib
2 custom class填写MyXibView
3 添加协议
4 MyXibView遵守协议
5 实现

protocol NibLoadable {
}

/// 加载xib
extension NibLoadable where Self: UIView {
    /* Xib 和 类名 同名
     * lazy var headerView = HomeHeaderView.loadFromNib()
     * Xib 和 类名 不同名
     *  lazy var sectionView = HomeHeaderView.loadFromNib("sectionView")
     * Xib 中多个 View 视图
     * lazy var sectionView = Level1SectionView.loadFromNib("Level1HeaderView",index: 1)
     * https://www.jianshu.com/p/cceeaaff0397
     */
    static func loadFromNib(_ nibname: String? = nil, index: Int = 0) -> Self { // Self(大写)当前类对象
        let loadName = nibname == nil ? "\(Self.self)" : nibname!
        return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)![index] as! Self
    }
}
class MyXibView: UIView, NibLoadable {
}
let myxibView:MyXibView = MyXibView.loadFromNib()

创建代码模版和XIB模版

第一步: command+shift+G 进入模版文件夹 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/iOS/Source/Cocoa Touch Class.xctemplate
第二步: 目录下创建 UIViewXIBSwift文件夹
第三步:模版复制

找到UIViewSwift文件夹下面的FILEBASENAME.swift文件,拷贝到UIViewXIBSwift文件夹
找到UIViewControllerXIBSwift文件夹下面的FILEBASENAME.xib文件,拷贝到UIViewXIBSwift文件夹

TemplateI_1.png
第四步:打开TemplateInfo.plist文件,cocoaTouchSubclass array添加plist字段UIView。

也可以通过系统文本编辑工具打开,cocoaTouchSubclass array中加入<string>UIView</string>

TemplateI_2.png
第五步:修改文件模版
TemplateI_3.png
第六步:修改XIB模版

删掉outlets 关联

TemplateI_4.png

添加文件custom class,和文件关联,和模块关联

TemplateI_5.png

把inferred改为fromdom才可以变更尺寸,然后只需要set 相关的 NSLayoutConstraint。

TemplateI_6.png

去掉自动适应
当你发现子视图无法添加约束时,进行下图修改
拖动imageview直接在view视图上不会产生这个问题。
拖动imageview和view同级,再拖到view视图会产生。

TemplateI_7.png

第六步:完全退出Xcode后,再打开。我们可以一步创建view和对应的xib了

我们会发现初始化代码,和预设xib属性都成功了


TemplateI_8.png

模版是根据第二种写法来创建的,当然也可以用Extension或者协议来扩展。个人偏好这一种。
当我们创建一个CustomXIBViewController后再创建一个CustomXIBView的时候,如果没有outlet会崩溃。因为命名问题,CustomXIBView和Controller.view默认关联了但是没有设置关联关系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容