Xib and Storyboard
Purpose
An Xib view allows you to create a single view that can be used in several places in the app. All modifications are made on a single view. An associated UIView file makes the view controller lighter, by hosting all the outlets.
XIB / NIB
Xib = Xcode Interface Builder
Nib = Nextstep Interface Builder
Create an Xib Custom View and storyboard
- Create a Xib file (New File/View)
GridView.xib
When you open this new file, you can create a custom view in Interface Builder.
You can choose the freedom shape in the attributes inspector. This will let you click on the view and change the shape as you see.
- Create a custom UIView file (New File/Cocoa Touch/UIView)
Give it the same name as the associated xib view
GridView.swift
- Connect XIB file and custom UIView
Click back into the Xib file. In the File's Owner placholders, enter the name of the UIView file as Class, in the Identity inspector.
GridView
- UIView Initializers
As a UIView can be created in the interface builder (storyboard, Xib) or programmatically in code, there is an initialiser for each.
In GridView.swift
file, add these two classic initializers, and a function to load the xib.
class GridView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
loaderNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loaderNib()
}
private func loaderNib() {
Bundle.main.loadNibNamed("GridView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
`
The first line will search for the loaded xib by name. Then the view is added with the ability to adapt to the dimensions of the container view that will display it in the storyboard.
There are other methods you may prefer. The choice is yours.
- Link the Xib custom view and its objects to the UIView file
Create an outlet for the Xib view
@IBOutlet var contentView: UIView!
Then one for each object and action (@IBAction)
@IBOutlet weak var gridButtons: [UIButton]!
@IBAction func chooseImage(_ sender: UIButton) {
}
Using this custom view in the storyboard
In the storyboard, add a UIView that will contain the xib view. Link this view with an outlet to the view controller.
class ViewController: UIViewController { @IBOutlet weak var gridView: GridView! override func viewDidLoad(){ ... }
The type of this view is the custom view of the xib.
You have access to the properties and methods defined in the GridView.swift
gridView.gridButtons[1].setBackgroundImage(currentImage, for: .normal)
UIButton Action
One way to manage the action of a button is to create a property
var currentButton: (() -> Void)? = nil
And to implement the IBAction as follows :
@IBAction func chooseImage(_ sender: UIButton) {
if let currentButton = self.currentButton {
currentButton()
}
}
In the controller, you can get the action and implement it. For example to call an image picker.
private func selectImage() {
gridView.currentButton = {
self.imagePicker.allowsEditing = true
self.imagePicker.sourceType = .photoLibrary
self.present(self.imagePicker, animated: true)
}
}
the final word
The size of the xib view does not matter, as it will fit the container view of the storyboard(or code)
Have fun with code