Reputation: 218
I work with Nibs. I have two screens that will use the "same" UIView
component with the same behavior. It's not the same component because in each screen i placed a UIView
and made the same configuration, as show on the image.
To solve this and prevent replicate the same code in other classes i wrote one class, that is a UIView
subclass, with all the functions that i need.
After that i made my custom class as superclass of these UIView
components to inherit the IBOutlets
and all the functions.
My custom class is not defined in a Nib
, is only a .swift
class.
I made all the necessary connections but at run time the IBOutlets
is Nil
.
The code of my custom class:
class FeelingGuideView: UIView {
@IBOutlet weak var firstScreen: UILabel!
@IBOutlet weak var secondScreen: UILabel!
@IBOutlet weak var thirdScreen: UILabel!
@IBOutlet weak var fourthScreen: UILabel!
private var labelsToManage: [UILabel] = []
private var willShow: Int!
private var didShow: Int!
override init(frame: CGRect) {
super.init(frame: frame)
self.initLabelManagement()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initLabelManagement()
}
private func initLabelManagement() {
self.initLabelVector()
self.willShow = 0
self.didShow = 0
self.setupLabelToShow(label: labelsToManage[0])
self.setupLabels()
}
private func initLabelVector() {
self.labelsToManage.append(self.firstScreen)
self.labelsToManage.append(self.secondScreen)
self.labelsToManage.append(self.thirdScreen)
self.labelsToManage.append(self.fourthScreen)
}
private func setupLabels() {
for label in labelsToManage {
label.layer.borderWidth = 2.0
label.layer.borderColor = UIColor(hex: "1A8BFB").cgColor
}
}
func willShowFeelCell(at index: Int) {
self.willShow = index
if willShow > didShow {
self.setupLabelToShow(label: labelsToManage[willShow])
}
else if willShow < didShow {
for i in didShow ... willShow + 1 {
let label = labelsToManage[i]
self.setupLabelToHide(label: label)
}
}
}
private func setupLabelToShow(label: UILabel) {
label.textColor = UIColor.white
label.backgroundColor = UIColor(hex: "1A8BFB")
}
private func setupLabelToHide(label: UILabel) {
label.textColor = UIColor(hex: "1A8BFB")
label.backgroundColor = UIColor.white
}
}
I found this question similar to mine: Custom UIView from nib inside another UIViewController's nib - IBOutlets are nil
But my UIView
is not in a nib.
EDIT:
I overrided the awakeFromNib
but it neither enter the method.
More explanation:
My custom class is only superClass of this component:
Which i replicate on two screens.
One screen is a UITableViewCell
and the another a UIViewController
.
It's all about to manage the behavior of the labels depending on the screen that is showing at the moment on the UICollectionView
When the initLabelVector()
function is called at the required init?(coder aDecoder:)
it arrises a unwrap error:
The error when try to open the View
:
Cannot show the error with the UITableViewCell
because it is called at the beginning of the app and don't appear nothing. To show the error with the screen i needed to remove the call of the UITableViewCell
.
The UITableViewCell
is registered first with the tableView.register(nib:)
and after using the tableView.dequeueReusebleCell
.
The UIViewController
is called from a menu class that way:
startNavigation = UINavigationController(rootViewController: FellingScreenViewController())
appDelegate.centerContainer?.setCenterView(startNavigation, withCloseAnimation: true, completion: nil)
Upvotes: 1
Views: 1149
Reputation: 534885
The problem is this code:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initLabelManagement()
}
The trouble is that init(coder:)
is too soon to speak of the view's outlets, which is what initLabelManagement
does; the outlets are not hooked up yet. Put this instead:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
self.initLabelManagement()
}
As a test, I tried this:
class MyView : UIView {
@IBOutlet var mySubview : UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
print(#function, self.mySubview)
}
override func awakeFromNib() {
super.awakeFromNib()
print(#function, self.mySubview)
}
}
Here's the output:
init(coder:) nil
awakeFromNib() <UIView: 0x7fc17ef05b70 ... >
What this proves:
init(coder:)
is too soon; the outlet is not hooked up yet
awakeFromNib
is not too soon; the outlet is hooked up
awakeFromNib
is called, despite your claim to the contrary
Upvotes: 4
Reputation: 218
When the init()
from my custom class is called the IBOutlets
are not hooked up yet.
So, I created a reference on the parent view and called the iniLabelManagement()
from the viewDidLoad()
method and everything worked.
Thank you matt, for the help and patience!
Upvotes: 1