How to embed a custom view xib in a storyboard scene?

前端 未结 11 547
生来不讨喜
生来不讨喜 2021-01-29 21:33

I\'m relatively new in the XCode/iOS world; I\'ve done some decent sized storyboard based apps, but I didn\'t ever cut me teeth on the whole nib/xib thing. I want to use the sam

11条回答
  •  走了就别回头了
    2021-01-29 22:04

    A pretty cool and reusable way of doing this Interface Builder and Swift 4:

    1. Create a new class like so:

      import Foundation
      import UIKit
      
      @IBDesignable class XibView: UIView {
      
          @IBInspectable var xibName: String?
      
          override func awakeFromNib() { 
              guard let name = self.xibName, 
                    let xib = Bundle.main.loadNibNamed(name, owner: self), 
                    let view = xib.first as? UIView else { return }    
              self.addSubview(view)
          }
      
      }
      
    2. In your storyboard, add a UIView that will act as the container for the Xib. Give it a class name of XibView:

    3. In the property inspector of this new XibView, set the name of your .xib (without the file extension) in the IBInspectable field:

    4. Add a new Xib view to your project, and in the property inspector, set the Xib's "File's Owner" to XibView (ensure you've only set the "File's Owner" to your custom class, DO NOT subclass the content view, or it will crash), and again, set the IBInspectable field:

    One thing to note: This assumes that you're matching the .xib frame to its container. If you do not, or need it to be resizable, you'll need to add in some programmatic constraints or modify the subview's frame to fit. I use snapkit to make things easy:

    xibView.snp_makeConstraints(closure: { (make) -> Void in
        make.edges.equalTo(self)
    })
    

    Bonus points

    Allegedly you can use prepareForInterfaceBuilder() to make these reusable views visible in Interface Builder, but I haven't had much luck. This blog suggests adding a contentView property, and calling the following:

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        xibSetup()
        contentView?.prepareForInterfaceBuilder()
    }
    

提交回复
热议问题