Load view from an external xib file in storyboard
My full example is here, but I will provide a summary below.
Layout
Add a .swift and .xib file each with the same name to your project. The .xib file contains your custom view layout (using auto layout constraints preferably).
Make the swift file the xib file's owner.
Code
Add the following code to the .swift file and hook up the outlets and actions from the .xib file.
import UIKit
class ResuableCustomView: UIView {
let nibName = "ReusableCustomView"
var contentView: UIView?
@IBOutlet weak var label: UILabel!
@IBAction func buttonTap(_ sender: UIButton) {
label.text = "Hi"
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view)
contentView = view
}
func loadViewFromNib() -> UIView? {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}
Use it
Use your custom view anywhere in your storyboard. Just add a UIView
and set the class name to your custom class name.
Reuse a uiview xib in storyboard
Reuse and render a xib in a storyboard.
Tested with Swift 2.2 & Xcode 7.3.1
1 ---- Create a new UIView named 'DesignableXibView'
- File > New > File > Source > Cocoa Touch Class > UIView
2 ---- Create a matching xib file named 'DesignableXibView'
- File > New > File > User Interface > View
3 ---- Set the file owner of the of the xib
- select the xib
- select file's owner
- set custom class to 'DesignableXibView' in the Identity Inspector.
- Note: Do not set the custom class of the view on the xib. Only the File Owner!
4 ---- DesignableXibView's Implementation
// DesignableXibView.swift
import UIKit
@IBDesignable
class DesignableXibView: UIView {
var contentView : UIView?
override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
func xibSetup() {
contentView = loadViewFromNib()
// use bounds not frame or it'll be offset
contentView!.frame = bounds
// Make the view stretch with containing view
contentView!.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(contentView!)
}
func loadViewFromNib() -> UIView! {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: String(self.dynamicType), bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
}
5 ---- Test your reuseable view in a storyboard
- Open your storyboard
- Add a view
- Set that view's Custom Class
- wait a sec ... BOOM!!
Be able to load xib from both Storyboard and ViewController
To preserve both cases, I preferred to write this inside my subclass declaration:
@IBDesignable class CustomView: UIView {
var view: UIView!
@IBOutlet weak var button: UIButton!
@IBOutlet weak var label: UILabel!
func xibSetup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "CustomView", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
}
In this way I can see and add it inside my storyboard
.
In ViewForHeaderInSection
method, I wrote this:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = UIView()
let view:CustomView = CustomView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 30))
view.label.text = "header title: \(section)"
header.addSubview(view)
return header
}
And so it works ;)
Related Topics
Shift Elements in Array by Index
Xcode 6 iPhone Simulator Application Support Location
Insert CSS into Loaded HTML in Uiwebview/Wkwebview
Change Tab Bar Item Selected Color in a Storyboard
Apns (Apple Push Notification Service) Reliability
Programmatically Creating an Expanding Uitableviewcell
Uialertview First Deprecated iOS 9
Uigraphicsgetimagefromcurrentimagecontext Memory Leak with Previews
Is It Considered a Private API to Use App-Prefs:Root
Setting Direction for Uiswipegesturerecognizer
How to Get the Console Logs from the iOS Simulator
Loading an Image into Uiimage Asynchronously
Uidatepicker Select Month and Year
Parsing Nested Array of Dictionaries Using Object Mapper
Presentviewcontroller:Animated:Yes View Will Not Appear Until User Taps Again