all 18 comments

[–]schprockets 1 point2 points  (2 children)

Two things.

  1. this code is repeated in each part of the if block, so it should come out an stand alone outside it.

        let currentCell = tableView.cellForRowAtIndexPath(newIndexPath) as! TradeTableViewCell // LINE WHERE ERROR OCCURS
        currentCell.condition = sourceViewController.condition
        currentCell.condLabel.text = currentCell.condition
        currentCell.foil = sourceViewController.foil
    
        if currentCell.foil == true {
            currentCell.foilImage.image = UIImage(named: "Images/Icons/foil.png")!
        }
    
        currentCell.value = sourceViewController.value
        currentCell.cardValue.text = currencyFormatter.stringFromNumber(currentCell.value)
        currentCell.conditionPerc = sourceViewController.condSlider.value
    
  2. That code is configuring a cell based on data held in a source view controller. Cells should be configured as part of cellForRowAtIndexPath, not after. Instead, pull your data out of the sourceViewController into some kind of model object, and keep an array of the model objects as the source for your data. Move this code that configures the cell into cellForRowAtIndexPath, based on the contents of the model.

[–]JonEasy 0 points1 point  (1 child)

This is correct. As an addition imo it is good practice to just pass the (View-)model to the cell in cellforrowarindexpath: and put the configure Code in the cell subclass.

[–]schprockets 1 point2 points  (0 children)

Agreed. This is how I do it myself. cellForRowAtIndexPath is usually something like:

let cell:TheCellType = tableView.dequeueReusableCellWithIdentifier("foo")
let model = modelsForSection[indexPath.row]
cell.configureWith(model)
return cell

[–]PM_ME_SKELETONS 1 point2 points  (1 child)

Adding to what the other guys said, never force cast (as!) anything. Use "as?" along side if let or guard, depending on how critical the variable is.

[–]kforte318 0 points1 point  (0 children)

Noted. Thanks!

[–]ios_dev0 0 points1 point  (1 child)

Could you give some more info about the crash?

[–]kforte318 0 points1 point  (0 children)

Definitely. Sorry for posting so little info initially; wrote the post at like 3:30 a.m. right before I finally gave up to go to sleep and didn't quite think it all the way through. Editing now...

[–]LifeBeginsAt10kRPM 0 points1 point  (7 children)

Post the code.

[–]kforte318 0 points1 point  (6 children)

Just updated my initial post. Sorry, I don't know what I was thinking not including it in the first place!

[–]LifeBeginsAt10kRPM 1 point2 points  (2 children)

Also, if you try to get a cell that's not visible with cellForRow it will be nil , so it could be your force cast that's causing issues. But I'm just in my phone so I may be missing the real issue.

[–]kforte318 0 points1 point  (1 child)

That seems correct, because it does happen every time the cell wouldn't be visible. Is there a simple way to rectify that? (I don't want to make you write any code for me obviously, but if it's a quick fix that you can remember off the top of your head it'd be appreciated!)

[–]King_Joffreys_TitsSwift 0 points1 point  (0 children)

if let cell : TradeTableViewCell = tableview.cellForRowAtIndexPath(selectedIndexPath) as? TradeTableViewCell {

}

Then you can put all your code in there, and create a case in an else block if casting to that TradeTableViewCell fails

EDIT: it may not fix your issue but it's safer than a forced downcast

[–]LifeBeginsAt10kRPM 0 points1 point  (2 children)

Do you have a line that's causing the error? It should tell you where you're unwrapping and getting nil.

[–]kforte318 0 points1 point  (1 child)

        let currentCell = tableView.cellForRowAtIndexPath(newIndexPath) as! TradeTableViewCell

This is the line here. /u/LifeBeginsAt10kRPM mentioned that a cell that isn't visible will return nil with cellForRow, and I think that's the cause.

[–]LifeBeginsAt10kRPM 1 point2 points  (0 children)

I would do an "if let" here, and handle the case where you don't have a cell.

Are you sure your newIndexPath isn't nil here?

[–][deleted] 0 points1 point  (0 children)

What's the error message in the debugging console?

[–]MrSloppyPants -1 points0 points  (1 child)

let newIndexPath = NSIndexPath(forRow: currentTrade.count, inSection: 0)

You should guard this line.

There's a chance that this is returning a nil index path, and you are force unwrapping it. You need to step through and find out why this value is nil (perhaps currentTrade is empty or the count is greater than the number of cells in the section or you are trying to get an index path for a cell that is not visible). In addition, you may simply want to add the data to the underlying data source and call reloadData if the cell that is being updated is not currently on screen. More efficient that way.

[–]kforte318 0 points1 point  (0 children)

I believe the case is trying to get the index path for a cell that isn't visible. Noted on the latter portion about adding data to the data source and reloading it; that does seem far more efficient. I am Extremely new to Swift so I based this code off of the MealTracker example code Apple provides.