Search code examples
swiftxib

Load .xib file from framework


I create a framework with Custom View. When I'm try to load this to simulator, it loads but when there's a bug when load in deferent iPhone simulators.

I set the constraints to 0, but the custom view doesn't load in all view.

framework code:

@IBDesignable
public class SummaryHeaderView: UIView {
    
    /* View */
    @IBOutlet public var view: UIView!
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setUpNib()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setUpNib()
    }
    
    internal func setUpNib() {
        view = loadNib()
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
    }

    internal func loadNib() -> UIView {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: SummaryHeaderView.self), bundle: bundle)
        guard let summaryHeaderView = nib.instantiate(withOwner: self, options: nil).first as? UIView else {
            return UIView()
        }
        return summaryHeaderView
    }
    
}

app code:

@IBOutlet weak var myView: UIView!

var summary = SummaryHeaderView()

override func viewDidLoad() {
    super.viewDidLoad()
    summary = SummaryHeaderView(frame: self.myView.bounds)
    
    myView.addSubview(summary)
}

Result:

enter image description here


Solution

  • One serious problem with your code is this:

    override func viewDidLoad() {
        super.viewDidLoad()
        summary = SummaryHeaderView(frame: self.myView.bounds)
    }
    

    You are assuming here that self.myView.bounds is known at the time viewDidLoad runs. That assumption is wrong. viewDidLoad is too soon for that. Therefore your summary header view shows at the wrong size.

    A simple solution would be: instead of using absolute frames everywhere, use auto layout constraints everywhere. That way, all your views and subviews will adjust themselves automatically no matter how big the screen turns out to be.

    Another way to do this is to wait until the size of the view is known. For example, move your code into viewDidLayoutSubviews. But then you must take extra steps so that you don't add the subview again later, because viewDidLayoutSubviews can be called many times during the app's lifetime.