iOS - 如何使用来自 NIB 的特定框架初始化自定义 UIView

5 init xib uiview ios swift

我想知道UIView用特定框架初始化自定义的最干净的方法是什么。

UIView从设计XIB文件。

这是我的实现

class CustomView : UIView {

    @IBOutlet var outletLabel: UILabel!

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

    public override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    private func setupView() {

        // Set text for labels
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我想在我的 ViewController 中初始化它的方式:

let screenSize: CGRect = UIScreen.main.bounds
let screenWidth = screenSize.width
let frame = CGRect(x: 0, y: 0, width: screenWidth - 50, height: 70)

let customView = CustomView.init(frame: frame)
Run Code Online (Sandbox Code Playgroud)

但它不起作用,我有一个没有任何插座的白色 UIView。

如果我这样做:

// Extension to UIView to load Nib
let customView : CustomView = UIView.fromNib()
Run Code Online (Sandbox Code Playgroud)

我可以看到我的viewXIB文件,其宽度/高度在Interface Builder.

我想用特定的框架加载view来自XIB文件的 BUT 是什么?

我是否缺少有关初始化的信息?

GIJ*_*JOW 4

You can have a NibLoading class like:

// NibLoadingView.swift
//source:https://gist.github.com/winkelsdorf/16c481f274134718946328b6e2c9a4d8
import UIKit

// Usage: Subclass your UIView from NibLoadView to automatically load a xib with the same name as your class

@IBDesignable
class NibLoadingView: UIView {

    @IBOutlet weak var view: UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        nibSetup()
    }

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

    private func nibSetup() {
        backgroundColor = .clear

        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.translatesAutoresizingMaskIntoConstraints = true

        addSubview(view)
    }



    private func loadViewFromNib() -> UIView {
        let bundle = Bundle(for: type(of:self))
        let nib = UINib(nibName: String(describing: type(of:self)), bundle: bundle)
        let nibView = nib.instantiate(withOwner: self, options: nil).first as! UIView
        nibView.anchorAllEdgesToSuperview()
        return nibView
    }

}

extension UIView {
    func anchorAllEdgesToSuperview() {
        self.translatesAutoresizingMaskIntoConstraints = false
        if #available(iOS 9.0, *) {
            addSuperviewConstraint(constraint: topAnchor.constraint(equalTo: (superview?.topAnchor)!))
            addSuperviewConstraint(constraint: leftAnchor.constraint(equalTo: (superview?.leftAnchor)!))
            addSuperviewConstraint(constraint: bottomAnchor.constraint(equalTo: (superview?.bottomAnchor)!))
            addSuperviewConstraint(constraint: rightAnchor.constraint(equalTo: (superview?.rightAnchor)!))
        }
        else {
            for attribute : NSLayoutAttribute in [.left, .top, .right, .bottom] {
                anchorToSuperview(attribute: attribute)
            }
        }
    }

    func anchorToSuperview(attribute: NSLayoutAttribute) {
        addSuperviewConstraint(constraint: NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: superview, attribute: attribute, multiplier: 1.0, constant: 0.0))
    }

    func addSuperviewConstraint(constraint: NSLayoutConstraint) {
        superview?.addConstraint(constraint)
    }
}
Run Code Online (Sandbox Code Playgroud)

Then your view will subclass the NibLoadingClass like:

class YourUIView: NibLoadingView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
Run Code Online (Sandbox Code Playgroud)

Set your XIB class in File's Owner like: In this case it will be YourUIView

在此输入图像描述

Then instantiate it:

let myView = YourUIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width-60, height: 170))
Run Code Online (Sandbox Code Playgroud)

  • 同意上一条。评论。将一个视图包装在另一个视图中只是为了设置它的框架绝对是个坏主意。 (2认同)