Why am I getting a nil for a UITableViewCell's UILabel? - swift

Why am I getting a 'nil' error/UILabel during my second pass thru the table cell listing iteration?
1) Inside cell
2) Inside cell
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) po cell?.contentView.viewWithTag(TitleLabelTag)
nil
Here I link the elements in the code; and register the cell:
class DiaryTableViewCell: UITableViewCell {
#IBOutlet weak var TitleLabel: UILabel!
#IBOutlet weak var SubTitleLabel: UILabel!
#IBOutlet weak var leftImageView: UIImageView!
#IBOutlet weak var rightImageView: UIImageView!
}
class DiaryTableViewController: UITableViewController {
let kCellIdentifier = "DiaryCell"
var cellNib:UINib?
var diaryCell:DiaryTableViewCell?
var objects = NSMutableArray() //...global var.
override func viewDidLoad() {
self.title = "My Diary"
cellNib = UINib(nibName: "TableViewCells", bundle: nil)
tableView.registerClass(DiaryTableViewCell.self, forCellReuseIdentifier: kCellIdentifier)
}
...
Yet I'm getting the runtime error here:
Here's what I get in the console:
1) Inside cell
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) po cell!.TitleLabel
nil
What's missing here?

It's a pretty bad idea to select a view with a tag. It's a much better idea to subclass your UITableViewCell and give it a property to access the elements.

If you are creating static cells and loading you need to create an IBoutlet for them in your .h correctly.
Moreover remove line
tableView.registerClass(...) statement from your code. Look at this link might help and is very similar except its for collectionview. -
Why is UICollectionViewCell's outlet nil?

1) I moved the cell registration to the viewDidLoad().
2) I forgot to place the '?' after the TitleLabel & SubTitleLabel; to notify the compiler that these labels could be nil.
I don't see the altered cell yet (empty rows); but I'm not getting runtime errors.
Unfortunately I merely cured the symptom; not the cause. I'm still getting nil UILabels.
...working on revision and cleaner code.

Related

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 2 years ago.
My Swift program is crashing with a fatal error, saying that "Unexpectedly found nil while implicitly unwrapping an Optional value" even with the GUARD statement . Can anyone help to tell me why, and how do I fix it? The code as follows:
var page: Page? {
didSet{
guard let unwrappedPage = page else { return }
NameLabel.text = unwrappedPage.dishName
Image.image = UIImage(named: unwrappedPage.imageName)
contentText.text = unwrappedPage.ingredient
contentText.text = unwrappedPage.instruction
}
}
The issue is likely that the outlets have not been hooked up by the time you set page, and if these outlets are implicitly unwrapped optionals (with the ! after the type name, e.g. UILabel!), that will result in the error you describe. This problem will manifest itself if, for example, you set page before the view controller in question has been presented and all of the outlets have been hooked up.
So, I’d recommend:
Use optional chaining with your #IBOutlet references so it won’t fail if the outlets haven’t been hooked up yet.
Go ahead and keep your didSet observer on page, if you want, but make sure you also update the controls in viewDidLoad in case page was set before the outlets were hooked up.
For example:
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var imageView: UILabel!
#IBOutlet weak var ingredientLabel: UILabel!
#IBOutlet weak var instructionLabel: UILabel!
var page: Page? { didSet { updateControls(for: page) } }
override func viewDidLoad() {
super.viewDidLoad()
updateControls(for: page)
}
func updateControls(for page: Page?) {
nameLabel?.text = page?.dishName
imageView?.image = page.flatMap { UIImage(named: $0) }
ingredientLabel?.text = page?.ingredient
instructionLabel?.text = page?.instruction
}
Note, you only need this didSet observer if the page might be set (again) after the view has been presented. If not, the didSet observer is not needed.

Error message when setting UICollectionView data source and delegate with custom class

I am creating a sort of manual slideshow (i.e., the pictures move when the user taps a forward or backward button), and it is made with a Collection View. I had to create a custom collection cell view class, which I finished, but now I'm getting an error message in the iOS Simulator, "fatal error: unexpectedly found nil while unwrapping an Optional value" even though my code builds successfully. The error is in the ibCollectionView.dataSource = self line, and because I'm new to Swift and OOP (I learned about a month ago for the first time), I am confused by this error message, especially because there are no ? operators. I have included the problem part of my code (the part Xcode showed with the error message) below. Thank you!
import UIKit
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
//MARK: - Collection View Properties
#IBOutlet weak var ibCollectionView: UICollectionView!
#IBOutlet weak var ibCollectionViewLayout: UICollectionViewLayout!
var cellArray:[customCollectionViewCell] = Array(repeatElement(customCollectionViewCell(), count: 6))
let displayedCellDimensions = CGSize(width: 343, height: 248)
//MARK: - Xcode-generated Methods
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
//My code for this class continues down here...
First and most important thing is to check the IBOutlet connection
that you made in your storyboard.
Try to remove the connection in storyboard and then reconnect it.
Secondly put a debugger on to check if it's still nil.
ibCollectionView.dataSource = self
I think you forgot about this:
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
ibCollectionView?.register(YourCustomCell.self, forCellWithReuseIdentifier: "Cell")
And use "Cell" identifier in cellForItemAt...

Swift Can't initializing UIImageView and causes fatal error: unexpectedly found nil

I'm using xcode 8.2.1
fatal error: unexpectedly found nil while unwrapping an Optional value
This is the code,
class ShowMediaViewController: UIViewController {
var image: UIImage?
var titreText: String!
#IBOutlet var imageView: UIImageView!
//i tried #IBOutlet weak var imageView: UIImageView! but didn't work
#IBOutlet weak var titre: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
if image != nil {
//crashes here, because imageView is nil
imageView.image = image
} else {
print("image not found")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The code seems to crash at this line
imageView.image = image
I think is because imageView is nil?, cause i tried
print(image)
and came out fine, and then
print(imageView), it causes fatal error
But i did initializing it
#IBOutlet var imageView: UIImageView!
Maybe something's wrong with my storyboard?
Any help would be much appreciated
**
UPDATE 1
Connection Inspector
pic 1
pic 2
**
I had the same problem. I tried following steps. then It works.
Try these things,
Check the imageView bind to the storyBoard properly.
Clean and Build the project.
if not works
Close and restart XCode
Remove imageView from storyBoard add again imageView and bind again.
You're probably missing a connection from your view to the outlet. Check these:-
1) clicking on a dot next to the outlet in the code shows a connection to the storyboard
2) the outlets window for the image shows a connection to the code

UILabel provides nil value

I have two view controllers. 1st view controller fetches the user's location and has a delegate method. 2nd view controller conforms to the delegate method of 1st VC. I have a UILabel in 2nd VC which displays the location received from delegate method.
#IBOutlet var locationLabel: UILabel!
func locationOfTheUser(location: String) {
locationLabel.text=location
}
The locationLabel is connected in IB as an reference outlet.
But when i run the program it gives me an error saying that unexpectedly found nil value while unwrapping the optional.
You should declare your label like this:
#IBOutlet var weak locationLabel: UILabel!
The mention "#IBOutlet" makes Interface Builder recognize the outlet.
"Weak" is used because in most situations the owner of the outlet isn't the same as the owner of the view. For example, a view controller doesn't own someLabel - the view controller's view does.
For example, if there is a code path that removes an outlet from its superview, or the outlet is (intentionally) not hooked up in the storyboard, it needs to be an optional because the outlet is not guaranteed to be there when it's accessed.
#IBOutlet var someLabel: UILabel?
If there is no code path that re-adds the outlet to the view hierarchy, it would also be good to make it weak to not hold on to it unnecessarily when it gets removed:
#IBOutlet weak var someLabel: UILabel?
This ensures that if the label is removed from the superview, it's not being kept in memory by the strong reference in the view controller. In the most common case, where there is an outlet that will always be there, a strong, implicitly unwrapped optional is appropriate:
#IBOutlet var someLabel: UILabel!
The outlet isn't weak in case the code ever changes so that there is a code path that removes the view from the view hierarchy but you forget to update the optionality of the property. The object will stay in memory and using it won't crash your app.
Also, "var" is used because outlets are, by definition, set after initialization
You can after put your code:
func locationOfTheUser(location: String) {
locationLabel.text=location
}
private var locationOfUser: String?
func locationOfTheUser(location: String) {
locationOfUser = location
}
override func viewDidLoad() {
super.viewDidLoad()
locationLabel.text = locationOfUser
}
Try this. If it works, it means that the locationOfTheUser() is being called before the view of this controller has been loaded, therefore the label is not there yet.
#IBOutlet weak var heartbeats: UILabel!
guard heartbeats?.text != nil else {
print("The label is empty")
return
}
To check if the uilabel is really empty.

UITextView.text can't take a variable of type String?

There are very confusion things going on...
I try to set a text from the UITextView via UITextView.text = myVar but this won't work, every time i run this code this exception is shown:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
#IBOutlet weak var myTextView: UITextView!
let myStringVar: String = "I am a test string"
myTextView.text = myStringVar
But this peace of code works very well:
#IBOutlet weak var myTextView: UITextView!
myTextView.text = "I am a test string"
Why is that so? Can anyone help me?
insert print(myTextView) before myTextView.text = myStringVar and check, if myTextView not nil.