Reputation: 353
I am trying to update a UITableviewcell's label in other method. I also saw many post on stackoverflow, non was work for me. i am using Swift 3 and I tried this one :
let indexPath = IndexPath.init(row: 0, section: 0)
let cell : CategoryRow = tableView.cellForRow(at: indexPath) as! CategoryRow
and i am getting this error :
fatal error: unexpectedly found nil while unwrapping an Optional value
i am using this in other method where i update tableviewcell label text after 24hr. code is here
var myQuoteArray = ["“If you have time to breathe you have time to meditate. You breathe when you walk. You breathe when you stand. You breathe when you lie down. – Ajahn Amaro”","We are what we repeatedly do. Excellence, therefore, is not an act but a habit. – Aristotle","The best way out is always through. – Robert Frost","“If you have time to breathe you have time to meditate. You breathe when you walk. You breathe when you stand. You breathe when you lie down. – Ajahn Amaro”","We are what we repeatedly do. Excellence, therefore, is not an act but a habit. – Aristotle","The best way out is always through. – Robert Frost"
]
func checkLastRetrieval(){
// let indexPath = IndexPath.init(row: 0, section: 0)
// let cell : CategoryRow = tableView.cellForRow(at: indexPath) as? CategoryRow
let indexPath = IndexPath.init(row: 0, section: 0)
guard let cell = tableView.cellForRow(at: indexPath) as? CategoryRow else { return }
print("Getting Error line 320")// This is not printing on console
let userDefaults = UserDefaults.standard
if let lastRetrieval = userDefaults.dictionary(forKey: "lastRetrieval") {
if let lastDate = lastRetrieval["date"] as? NSDate {
if let index = lastRetrieval["index"] as? Int {
if abs(lastDate.timeIntervalSinceNow) > 86400 { // seconds in 24 hours
// Time to change the label
var nextIndex = index + 1
// Check to see if next incremented index is out of bounds
if self.myQuoteArray.count <= nextIndex {
// Move index back to zero? Behavior up to you...
nextIndex = 0
}
cell?.quotationLabel.text = self.myQuoteArray[nextIndex]
let lastRetrieval : [NSObject : AnyObject] = [
"date" as NSObject : NSDate(),
"index" as NSObject : nextIndex as AnyObject
]
userDefaults.set(lastRetrieval, forKey: "lastRetrieval")
userDefaults.synchronize()
}
// Do nothing, not enough time has elapsed to change labels
}
}
} else {
// No dictionary found, show first quote
cell?.quotationLabel.text = self.myQuoteArray.first!
print("line 357")
// Make new dictionary and save to NSUserDefaults
let lastRetrieval : [NSObject : AnyObject] = [
"date" as NSObject : NSDate(),
"index" as NSObject : 0 as AnyObject
]
userDefaults.set(lastRetrieval, forKey: "lastRetrieval")
userDefaults.synchronize()
}
}
and Calling this method in ViewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
checkLastRetrieval()
}
what should i do? Thanks in Advance
Upvotes: 0
Views: 96
Reputation: 114865
The function cellForRow(at:)
returns nil
if the requested cell is not currently onscreen. Since you are calling your function in viewDidLoad
there will be no cells on screen. This results in the crash because you have force downcast the result of cellForRow(at:)
.
You should never use a force unwrap or a force downcast unless you are absolutely
certain the result cannot be nil
and/or the only possible action if it is nil
is for your app to crash.
Generally you should not update cells directly. It is better to update the table's data model and then call reloadRows(at:,with:)
and let your data source cellForRow(at:)
function handle updating the cell.
If you are going to update the cell directly then make sure you use a conditional downcast with if let
or guard let
to avoid a crash if the cell isn't visible. In this case you still need to update your data model so that the cell data is correct when the cell does come on screen.
Upvotes: 1
Reputation: 4383
You should use guard let
statement:
let indexPath = IndexPath(row: 0, section: 0)
guard let cell = tableView.cellForRow(at: indexPath) as? CategoryRow else { return }
If your cell
type is not CategoryRow
, you will return from the method. Try to find out why is your cell
type not a CategoryRow
.
Upvotes: 0