TableViewCell not updating - ios

I have a TableView Controller with custom cells that I want reload with new data whenever the table view is loaded.
The problem I'm having is the data is reloading properly but the cell labels are not.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> JobTableViewCell{
jobSelect = Int(indexPath.row)
var cell: JobTableViewCell = tableView.dequeueReusableCellWithIdentifier("JobTableViewCell") as JobTableViewCell
if indexPath.row % 2 == 0{cell.backgroundColor = UIColor.lightGrayColor()
}
else {cell.backgroundColor = UIColor.whiteColor()}
var job = arrayOfJobs[indexPath.row]
var totalHours = job.monHours + job.tueHours + job.wedHours + job.thuHours + job.friHours + job.satHours + job.sunHours
cell.setCell(job.jobName, income: job.income, commute: job.commute, jobHours: totalHours)
return cell
}
Here is the custom cell -
import UIKit
class JobTableViewCell: UITableViewCell {
#IBOutlet var jobTitle: UILabel!
#IBOutlet var income: UILabel!
#IBOutlet var commute: UILabel!
#IBOutlet var jobHours: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
//fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setCell(jobTitle: String, income: Int, commute: Int, jobHours: Int){
self.jobTitle.text = String(arrayOfJobs[jobSelect
].jobName)
self.income.text = String("Income: $\(arrayOfJobs[jobSelect].income) a month")
self.commute.text = String("Commute: \(arrayOfJobs[jobSelect].commute) hours away from home")
self.jobHours.text = String("Available hours:\(arrayOfJobs[jobSelect].monHours + arrayOfJobs[jobSelect].tueHours + arrayOfJobs[jobSelect].wedHours + arrayOfJobs[jobSelect].thuHours + arrayOfJobs[jobSelect].friHours + arrayOfJobs[jobSelect].satHours + arrayOfJobs[jobSelect].sunHours) hours a week")
}
}
I also have a second view controller set up that appears when a cell is selected -
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
jobSelect = Int(indexPath.row)
var JobSelector: jobSubView = storyboard?.instantiateViewControllerWithIdentifier("jobSubView") as jobSubView
self.presentViewController(JobSelector, animated: true, completion: nil)
self.rowSelection = Int(indexPath.row)
}
Here is the sub view -
import UIKit
class jobSubView: UIViewController {
#IBOutlet var jobTitle: UILabel!
#IBOutlet var income: UILabel!
#IBOutlet var commute: UILabel!
#IBOutlet var jobHours: UILabel!
#IBOutlet var qualifications: UILabel!
#IBOutlet var jobDescription: UITextView!
#IBOutlet var goBackButton: UIButton!
#IBOutlet var appluButton: UIButton!
#IBAction func applyButtonAction(sender: UIButton) {
override func viewDidLoad() {
super.viewDidLoad()
self.jobTitle.text = String(arrayOfJobs[jobSelect
].jobName)
self.income.text = String("Income: $\(arrayOfJobs[jobSelect].income) a month")
self.commute.text = String("Commute: \(arrayOfJobs[jobSelect].commute) hours away from home")
self.jobHours.text = String("Available hours: \(arrayOfJobs[jobSelect].monHours + arrayOfJobs[jobSelect].tueHours + arrayOfJobs[jobSelect].wedHours + arrayOfJobs[jobSelect].thuHours + arrayOfJobs[jobSelect].friHours + arrayOfJobs[jobSelect].satHours + arrayOfJobs[jobSelect].sunHours) hours a week")
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
The labels on the cell and the subviews are drawing from the same data. When the tableview loads the first time both the cells and the sub view display correctly.
The subview loads with the correct data when a cell is selected, but when I return to the tableview the cell labels should update, but they are not. But the sub view labels are.
Any ideas?

So, I figured this out. You have to do self.tableView.reloadData() in viewWillAppear instead of viewDidLoad.

Related

Adding cell to Table view when button tapped in swift

i have to views in my app. mainMeasurements and historyMode. in main measurement, user can take photo and measure distance, speed and time. I need that app will save that measured datas in TableView in a historyMode, when reset button tapped (like a recents in a phone app). i already prepared datas and commented them. it should add cells to table view with image and "lastTop..." datas and show old ones too
class mainMeasurements: UIViewController, CLLocationManagerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var speedArray: [String] = []
var arrayOfImages: [UIImage] = []
var distanceArray: [Int] = []
var lastTopDistance: String?
var lastTopSpeed: String?
var lastTopTime: String?
#IBOutlet weak var takePhoto: UIButton!
#IBOutlet weak var mountainImage: UIImageView!
#IBOutlet weak var speedLabel: UILabel!
#IBOutlet weak var distanceLabel: UILabel!
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var resetButtonLabel: UIButton!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "switchToHistory"{
// let historyModeVc = segue.destination as! historyMode
// historyModeVc.memoryPhoto = arrayOfImages.last
// historyModeVc.historySpeedLabelMM = lastTopSpeed
// historyModeVc.historyDistanceLabelMM = lastTopDistance
// historyModeVc.historyTimerLabelMM = lastTopTime
}
}
#IBAction func resetDidTouch(_ sender: UIButton) {
arrayOfImages.append(mountainImage.image!)
self.lastTopSpeed = self.maxSpeed
self.lastTopDistance = self.distanceLabel.text
self.lastTopTime = self.timerLabel.text
self.arrayOfImages.append(self.mountainImage.image!)
}
}
AND
import UIKit
class historyMode: UIViewController {
var memoryPhoto: UIImage?
var historyTimerLabelMM: String?
var historySpeedLabelMM: String?
var historyDistanceLabelMM: String?
override func viewDidLoad() {
super.viewDidLoad()
// historyDistanceLabel.text = historyDistanceLabelMM
// historySpeedLabel.text = historySpeedLabelMM
// historyTimerLabel.text = historyTimerLabelMM
// historyImage.image = memoryPhoto
}
If I'm not mistaken, you're inquiring about how to display your data on a table view?
You can parse your data like this and pass it to historyMode:
struct YourData {
var arrayOfImages: [UIImage]
var lastTopDistance: String?
var lastTopSpeed: String?
var lastTopTime: String?
}
Create a custom cell:
class CustomCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// configure your cell UI
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func set(with data: YourData) {
// initialize your properties with the data you provide
}
}
Register your custom cell with historyMode and pass your data to the custom cell:
var yourDataArray: [YourData]!
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
let yourData = yourDataArray[indexPath.row]
cell.set(with: yourData)
return cell
}
Add new element to your dataSource and use NotificationCentre to call tableView.reloadData() in historyMode

Having trouble connecting my CustomCell.xib to my tableView in the storyboard

I Have to do an app for recipes and it shows me different recipes in my tableView, and i just want to implement my CustomCell (from a xib file) to my storyboard and I don't know how to connect it to show my data (I already checked my identifier) here's the code of my controller :
class SearchRecipe: UIViewController, ShowAlert {
var recipeData = RecipeDataModel()
var recipe = [String]()
#IBOutlet weak var tableViewSearch: UITableView!
override func viewDidLoad() {
self.tableViewSearch.rowHeight = 130
}
func updateRecipeData(json: JSON){
if let ingredients = json["hits"][0]["recipe"]["ingredientLines"].arrayObject{
recipeData.ingredientsOfRecipe = ingredients[0] as! String
recipeData.cookingTime = json["hits"][0]["recipe"]["totalTime"].stringValue
recipeData.recipe = json["hits"][0]["recipe"]["label"].stringValue
recipeData.recipeImage = json["hits"][0]["recipe"]["image"].stringValue
}
else {
print("Problem")
}
//self.tableViewSearch.reloadData()
}
}
extension SearchRecipe: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return recipe.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customRecipeCell", for: indexPath) as! CustomRecipeCell
getRecipesDisplay(in: cell, from: recipeData , at: indexPath)
return cell
}
func getRecipesDisplay(in cell: CustomRecipeCell, from recipeModel: RecipeDataModel, at indexPath: IndexPath){
cell.recipeTitle.text = recipeData.recipe
cell.recipeInfos.text = recipeData.ingredientsOfRecipe
cell.timerLabel.text = recipeData.cookingTime
}
}
and this is the code my xib file :
class CustomRecipeCell: UITableViewCell {
#IBOutlet weak var recipeTitle: UILabel!
#IBOutlet weak var recipeInfos: UILabel!
#IBOutlet weak var cellImageBackground: UIImageView!
#IBOutlet weak var likeAndTimerView: UIView!
#IBOutlet weak var likeImage: UIImageView!
#IBOutlet weak var timerImage: UIImageView!
#IBOutlet weak var likeLabel: UILabel!
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func awakeFromNib() {
super.awakeFromNib()
activityIndicator.isHidden = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
In ViewDidLoad, you must register your cell this way:
override func viewDidLoad() {
tableViewSearch.register(UINib(nibName:" /* NAME OF YOUR XIB FILE */ ", bundle: nil), forCellReuseIdentifier: "customRecipeCell")
}
You also have to edit the size of your cell in the attribute inspector of your custom cell and of your table view

didSelectRowAtIndexPath not getting called when row is pressed

I have 5 custom cells in a table view but didSelectRowAtIndexPath is not working for only one cell. I have added the cell for the row at the index for that cell in the code.
let cell : FileSentCell = chatTableView.dequeueReusableCell(withIdentifier: "fileSend") as! FileSentCell
let fileUrl = self.getImageURL(forFileName: fileNameString!)
if(fileUrl == nil){
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "fileDownloadWhite")
}else{
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "downloadedWhite")
}
cell.downloadStatusIndicator.isHidden = false
cell.downloadingIndicator.alpha = 0.0
cell.sendFileView.layer.cornerRadius = 10
cell.name.text = groupMsg.senderDisplayName
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
cell.fileStatus.text = groupMsg.status
cell.fileIcon.image = returnImage(fileName:groupMsg.message!)
cell.sendFileView.tag = indexPath.row
cell.sendFileView.addGestureRecognizer(longPressGesture)
cell.sendFileView.isUserInteractionEnabled = true
return cell
I have made UITableview have a single selection. and didSelectRowAtIndexPath is getting called for all the other reuse cells except for this one cell
Is there a reason or should I change some thing in the cellforat row
My FileSentCell class is
import UIKit
import QuartzCore
class FileSentCell: UITableViewCell {
#IBOutlet var sendFileView : UIView!
#IBOutlet var message : ChatLabel!
#IBOutlet var time : UILabel!
#IBOutlet var fileStatus : UILabel!
#IBOutlet var fileIcon : UIImageView!
#IBOutlet var downloadStatusIndicator : UIImageView!
#IBOutlet var downloadingIndicator: UIActivityIndicatorView!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
//fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)!
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
One more thing is if I reduce the width of UIView inside content view and click the row where UIView is not being displayed didSelectRow is getting called, So didSelectRow is not getting called only when it is clicked on the UIView inside content View
Thanks in Advance.
Set:
cell.contentView.isUserInteractionEnabled = true

Swift -> my prototype cell (UITableViewCell) doesn't show in my UIViewController with a UITableView

My storyboard looks like this
and my code is the following
UIViewController
class DownLoadSoundsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: View Controller Properties
let viewName = "DownLoadSoundsViewController"
#IBOutlet weak var visualEffectView: UIVisualEffectView!
#IBOutlet weak var dismissButton: UIButton!
#IBOutlet weak var downloadTableView: UITableView!
// MARK: Properties
var soundPacks = [SoundPack?]() // structure for downloadable sounds
override func viewDidLoad() {
super.viewDidLoad()
downloadTableView.dataSource = self
downloadTableView.delegate = self
downloadTableView.register(DownLoadTableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfSoundPacks
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let method = "tableView.cellForRowAt"
//if (indexPath as NSIndexPath).section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "downloadTableViewCell", for: indexPath) as! DownLoadTableViewCell
cell.backgroundColor = UIColor.green
if soundPacks[(indexPath as NSIndexPath).row]?.price == 0 {
cell.soundPackPriceUILabel.text = "FREE"
} else {
cell.soundPackPriceUILabel.text = String(format: "%.2", (soundPacks[(indexPath as NSIndexPath).row]?.price)!)
}
//cell.textLabel?.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackTitleUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackAuthorUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.author
cell.soundPackShortDescription.text = soundPacks[(indexPath as NSIndexPath).row]?.shortDescription
cell.soundPackImage.image = UIImage(named: "Placeholder Icon")
DDLogDebug("\(viewName).\(method): table section \((indexPath as NSIndexPath).section) row \((indexPath as NSIndexPath).row))")
return cell
//}
}
UItableViewCell
class DownLoadTableViewCell: UITableViewCell {
#IBOutlet weak var soundPackImage: UIImageView!
#IBOutlet weak var soundPackTitleUILabel: UILabel!
#IBOutlet weak var soundPackAuthorUILabel: UILabel!
#IBOutlet weak var soundPackShortDescription: UILabel!
#IBOutlet weak var soundPackPriceUILabel: UILabel!
let gradientLayer = CAGradientLayer()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
But I get the following;
I am sure I am doing something small incorrectly, but as of yet can't figure it out. Looked through many examples included my own code where I have gotten this working before.
Not a single one of my settings for the tableview are getting invoked except the number of cells. But everything in;
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{...}
is not working.
Help is appreciated.
I think you need to reload the tableView after getting data from Firebase
self.saveMixesTableView.reloadData()

Changing table from tableviewcontroller to regular view controller

Sorry if this kind of question isn't welcome here but I'd appreciate the help. I have a fully functioning table now set up but I did it using the TableViewController in storyboard. I now realize I cannot change the size of the view using that item and it doesn't fit well on the screen as is. I understand I need to use a regular view controller and add the table view manually. I can do that but I spent hours getting the table to work properly and I'm afraid to break it. Can someone walk me through transitioning between the two?
Here is the storyboard
Here is the view controller code
import UIKit
class CharacterTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var characterTableView: UITableView!
var characterArray: [Character] = [Character]()
override func viewDidLoad() {
super.viewDidLoad()
self.characterSetup()
}
func characterSetup() {
var admiralSwiggins = Character(name: "Admiral Swiggins", abilities: "Stun, Blind, Shield, Damage Over Time, Area of Effect", characterImage: "admiral.png")
var ayla = Character(name: "Ayla", abilities: "Area of Effect, Damage Over Time, Fly, Lifesteal, Shield, Slow", characterImage: "ayla.png")
var clunk = Character(name: "Clunk", abilities: "Lifesteal, Area of effect, Ensnare, Slow, Launch String", characterImage: "clunk.png")
characterArray.append(admiralSwiggins)
characterArray.append(ayla)
characterArray.append(clunk)
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:CharacterTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as CharacterTableViewCell
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor.redColor()
}
let character = characterArray[indexPath.row]
cell.nameLabel.text = character.name
cell.abilityLabel.text = character.abilities
cell.characterImage.image = UIImage(named: character.characterImage)
return cell
}
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
}
}
And here is the cell
import UIKit
class CharacterTableViewCell: UITableViewCell {
#IBOutlet var nameLabel: UILabel!
#IBOutlet var abilityLabel: UILabel!
#IBOutlet var characterImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

Resources