I'm trying to use a custom uiview that is in a xib file. I'm a beginner and don't know where to start. I have this so far, but I don't know what I should set my placeholder view equal to
edit: full viewController:
import UIKit
class Viewcontroller: UIViewController {
#IBOutlet weak var placeholderView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
placeholderView = view
}
class func instanceFromNib() -> CustomView {
let view = UINib(nibName: "CustomView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomView
return view
}
A. Let me suppose that you have a xib file titled 'TestView.' Also let me suppose that you have a subclass file of UIView titled 'TestView.'
B. Select your xib file. And select File's Owner. And set the class to TestView (the name of the subclass file).
C. Open the xib file with Interface Builder. Select 'Custom View.' (in the middle pane) IBOutlet-Connect this view to your UIView swift file. For example, name it like the following. #IBOutlet var customView: NSView!
D. This subclass file should have the following.
import UIKit
class TestView: UIView {
#IBOutlet var contentView: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
Bundle.main.loadNibNamed("TestView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
}
}
E. Open the storyboard. Drag and drop a Custom View onto the view controller scene. Under the identity inspect, set the class name to TestView.
F. IBOutlet-connect the custom view object in the view controller like the following.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var testView: TestView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
That's all.
Related
I'm trying to use custom views from xib files, but I don't know how to set the placeholder view in the storyboard equal to one of the xibs. Also, I can't just set the placeholder uiview's property to one of the xibs because I need to be able to switch between different xibs. This is what I have so far.
import UIKit
class Viewcontroller: UIViewController {
#IBOutlet weak var placeholderView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
placeholderView = view
}
class func instanceFromNib() -> CustomView {
let view = UINib(nibName: "CustomView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomView
return view
}
Create a custom class for your Xib view where you load the nib as follows:
class MyCustomView: UIView{
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit(){
Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)
}
}
You can add all of the outlets and stuff you need there.
The view in your storyboard must be of the type of your Xib view. Change it both in your code and in your storyboard:
#IBOutlet weak var placeholderView: MyCustomView!
From storyboard:
Click the view
Go to the identity inspector
In the class thing write MyCustomView
Instead of thinking in terms of a "placeholder" view that will be replaced by some other view, think about it as a "container" view... you would add the xib's view as a subview, just as you would add any other subview.
So, when you want to show the view from a xib, you would:
remove the current subview from the container (if one is already there)
load the view from the desired xib
add it as a subview to the container
set constraints relative to the container
Practicing MVC pattern and want to separate view from viewcontroller using storyboard.
in main.storyboard I have a viewcontroller, and there are some uilabels in rootview.
to separate view code from viewcontroller, I selected view from viewcontroller scene , created FruitDetailView class and subclassed it in storyboard identity inspector.
And connected UILabels to FruitDetailView class.
class FruitDetailView: UIView {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var type: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
name.text = ""
type.text = ""
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(_ detail: Fruit) {
name.text = detail.name
type.text = detail.type
}
}
In the viewController , created FruitDetailView() instance.
And in loadview() methods, assigned fruitDetailView instance to view property.
class FruitDetailViewController: UIViewController {
private let fruitDetailView = FruitDetailViewController()
var fruit = Fruit()
override func loadView() {
view = fruitDetailView
fruitDetailView.update(fruit)
}
}
But when I run the app, app crashes with error.
How can I fix this?
Your problem is you want to reach your FruitDetail class created before even its properties being created. Put a breakpoint to the name.text = "" and run and you will see what i mean. To solve this just control your nil value safely :
if let label = name { // by the way consider in future to assign values like nameLabel rather than name
name.text = "put your string value"
}
I have XIB file in which there is class of type UIView, and I wont to load that XIB in root ViewController:
import UIKit
class ViewController: UIViewController {
// MARK: - Variables
// MARK: - IBOutlets
#IBOutlet private weak var mainStackView: UIStackView!
// MARK: - LifeCycle Methods
override func viewDidLoad() {
super.viewDidLoad()
if let view = CustomView.instanceFromNib() {
let view = CustomView.instanceFromNib() as! CustomView
mainStackView.addArrangedSubview(view)
mainStackView.addArrangedSubview(view)
mainStackView.addArrangedSubview(view)
}
}
}
import Foundation
import UIKit
class CustomView: UIView {
static let id = "CustomView"
#IBOutlet weak var backgroundImageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
}
static func instanceFromNib() -> UIView {
return UINib(nibName: "UserReview", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
this class is not key value coding-compliant for the key backgroundImageView.'
Did you File owner for Xib file ?? assign CustomView class to Xib File's Owner
How do I work with a Label that hangs on a xib?
lblName.text = "Label Text"
I am getting error associated with
unexpectedly found nil while unwrapping an Optional value
You should update your custom View class in the following way.
First of all, open View.xib file set File's Owner custom class to View like the image in given below
after set UILabel IBOutlets like the image given below
After that open View.swift file and paste the code given below
class View: UIView {
private var view: UIView!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var firstname: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
//FIXME:- Set up
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: "View", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
}
Now you can variable of View class in ViewController.
I have created a .xib and adding this xib to another view. I want to add a delegate method in that .xib file. Here is my code :
.xib file
import UIKit
protocol CustomCheckBoxWithCrossDelegate {
func deleteCustomCheckbox(itemToDelete: String)
}
class CustomCheckBoxWithCross: UIView {
#IBOutlet weak var radioButton: UIButton!
#IBOutlet weak var checkboxLbl: UILabel!
#IBOutlet weak var checkboxCrossBtn: UIButton!
var blockIndexForTheCrossButton: Int = 0
var delegate: CustomCheckBoxWithCrossDelegate!
override init(frame: CGRect) {
super.init(frame: frame)
loadViewFromNib ()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadViewFromNib ()
}
func loadViewFromNib() {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "CustomCheckBoxWithCross", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
view.frame = bounds
view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.addSubview(view);
}
#IBAction func crossBtnTapped(sender: AnyObject) {
print("Delegate --> \(delegate)")
delegate!.deleteCustomCheckbox("hello")
}
}
But in "crossBtnTapped" method I am getting nil value for that delegate.
can anyone please tell me what I am doing wrong?
You must have the instance of CustomCheckBoxWithCross in your other class, where you have implemented the protocol. Set delegate property of CustomCheckBoxWithCross instance to self in that file.
I ran to this error several times before, add if delegate is not nil condition.
#IBAction func crossBtnTapped(sender: AnyObject) {
if delegate != {
delegate!.deleteCustomCheckbox("hello")
}
}