Reputation: 10520
I believe creating a custom class to configure a table cell is a standard practice of iOS development. I apply this practice to my app as well but I'm having some issue with it.
I have two tableviews - one for each ViewController
- that their cell is using the same custom cell class.
CustomCellClass
import UIKit
class RecipeCategoryCell: UITableViewCell {
@IBOutlet weak var recipeCategoryLabel: UILabel!
@IBOutlet weak var chooseCategoryLabel: UILabel!
//...
func configureCell(recipe: Recipe) {
let category = recipe.category as? RecipeCategory
recipeCategoryLabel.text = category!.name
}
func configureNewCell(category: RecipeCategory) {
recipeCategoryLabel.text = category.name
}
// re-configure receiver's viewcontroller cell with selected category value
func configureSelectedCategoryCell(selectedCategory: String) {
recipeCategoryLabel.text = selectedCategory
}
// configure all available category names in the sender's viewcontroller
func configureChooseCategoryCell(category: RecipeCategory) {
chooseCategoryLabel.text = category.name
}
}
@IBOutlet weak var recipeCategoryLabel: UILabel!
belongs to a receiver viewController and @IBOutlet weak var chooseCategoryLabel: UILabel!
belongs to a sender viewController
I have an issue at the 3rd function at this line recipeCategoryLabel.text = selectedCategory
that Xcode
says
fatal error: unexpectedly found nil while unwrapping an Optional value
I don't have this issue on other functions that uses the same IBOutlet recipeCategoryLabel
but only the function configureSelectedCategoryCell()
that re-configures receiver ViewController cell with selected category value.
So I can say for certainty that this is not a connection problem with storyboard.
I suppose this is happening because the same IBOutlet property is used in multiple places. But the thing is that, I have to use the same property so I can set default value, update the selected value, set previously persisted value on the same label.
I don't know if my explanation is clear enough but basically I cannot set the table cell label of receiver's ViewController
with the selected category value that was passed from the sender's ViewController
.
UPDATE
And configureSelectedCategoryCell()
is called in the receiver's ViewController extension:
extension CreateRecipeVC: RecipeCategoryTableVCDelegate {
func categoryController(controller: RecipeCategoryTableVC, didSelectCategory category: String) {
selectedCategory = category
self.navigationController?.popViewControllerAnimated(true)
let cell = RecipeCategoryCell()
cell.configureSelectedCategoryCell(selectedCategory)
}
}
Upvotes: 0
Views: 615
Reputation: 15042
The cell's outlets are not instantiated at the point when you try to access them in configureSelectedCategoryCell
.
As I understand the cells are designed in Interface Builder, so the outlets of the cell object cell
are missing the references to the controls in Interface Builder.
After a category is selected you should
Something like this:
func categoryController(controller: RecipeCategoryTableVC, didSelectCategory category: String) {
selectedCategory = category
self.navigationController?.popViewControllerAnimated(true)
tableViewDataSource[selectedItemIndex].selectedCategory = selectedCategory
tableView.reloadData()
}
Then in the table view data source delegate:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("YourCellIdentifer") as! RecipeCategoryCell
cell.configureSelectedCategoryCell(tableViewDataSource[indexPath.row].selectedCategory)
return cell
}
Side notes:
It is legit to connect one IBOutlet to multiple controls in the storyboard.
As precaution I suggest to remove the force unwrapping of an optional in configureCell
, e.g.
func configureCell(recipe: Recipe) {
if let category = recipe.category as? RecipeCategory {
recipeCategoryLabel.text = category.name
}
}
Upvotes: 1