1

I am trying to create an app that gets the input of the user and fills a class, then afterwards stores that data on an array that I want to retrieve and populate a UITableView.

My issue is that I can't figure it out for the life of me what is wrong exactly, since I learned how to code by myself, and I am sure that it will be something simple, yet, I just can't find out.

I am not getting any errors and searched for days to see if someone else had the same issue using an array of classes but no luck making it work so far.

I have tried to populate the class manually with pre defined strings, but this has not made any difference. I tried to print, and I see that nothing has been printed, hence why nothing is showing up on my UITableView. I have defined data source and delegate with no avail.

Here is my class and array:

class UserTrips {
        init(type: String = "Tourism", roundtrip: String = "True", departure: String = "March 10, 2024", arrival: String = "March 23, 2024", from: String = "YYZ", to: String = "OPO", vehicle: String = "Air") {
        }
    }
    
    let tripVariable = UserTrips()
    var tripsArray: [UserTrips] = [
        .init(type: "Tourism", roundtrip: "True", departure: "March 5, 2024", arrival: "March 10, 2024", from: "YYZ", to: "OPO", vehicle: "Air"),
        .init(type: "Tourism", roundtrip: "False", departure: "March 10, 2024", arrival: "March 23, 2024", from: "Toronto", to: "New York", vehicle: "Land")
        ]

Here is my viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tripsCellView.register(TripsTVC.nib(), forCellReuseIdentifier: TripsTVC.identifier)
        self.tripsCellView.delegate = self
        self.tripsCellView.dataSource = self
}

Here is tableView code:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tripsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let data = tripsArray[indexPath.row]
        
        if indexPath.row > 0 {
            let customCell = self.tripsCellView.dequeueReusableCell(withIdentifier: TripsTVC.identifier) as! TripsTVC
            customCell.configure(with: "Tourism", roundtrip: "True", departure: "March 10, 2024", arrival: "March 23, 2024", from: "YYZ", to: "OPO", vehicle: "Air")
            return customCell
        }
        
        return cell
    }

Any help would be very appreciated.

EDIT:

Current Code:

import UIKit

class Mainscreen: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    class UserTrips {
        
        init(type: String = "Tourism", roundtrip: String = "True", departure: String = "March 10, 2024", arrival: String = "March 23, 2024", from: String = "YYZ", to: String = "OPO", vehicle: String = "Air") {
        }
        
        var type: String = "Tourism"
        var roundtrip: String = "True"
        var departure: String = "March 10, 2024"
        var arrival: String = "March 23, 2024"
        var from: String = "YYZ"
        var to: String = "OPO"
        var vehicle: String = "Air"
    }
    
    let tripVariable = UserTrips()
    var tripsArray: [UserTrips] = [
        .init(type: "Tourism", roundtrip: "True", departure: "March 5, 2024", arrival: "March 10, 2024", from: "YYZ", to: "OPO", vehicle: "Air"),
        .init(type: "Tourism", roundtrip: "False", departure: "March 10, 2024", arrival: "March 23, 2024", from: "Toronto", to: "New York", vehicle: "Land")
        ]
    
    @IBOutlet weak var tripsCellView: UITableView!
    @IBOutlet weak var menuStack: UIStackView!
    @IBOutlet weak var addTripButton: UIButton!
    @IBOutlet weak var userAccountButton: UIButton!
    @IBOutlet weak var travelHistoryButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tripsCellView.register(TripsTVC.nib(), forCellReuseIdentifier: TripsTVC.identifier)
        self.tripsCellView.delegate = self
        self.tripsCellView.dataSource = self

        self.travelHistoryButton.layer.cornerRadius = 20
        self.travelHistoryButton.layer.masksToBounds = true
        self.travelHistoryButton.layer.borderWidth = 5
        self.travelHistoryButton.layer.borderColor = CGColor(red: 255/255, green: 59/255, blue: 48/255, alpha: 1)
        self.menuStack.layer.cornerRadius = 20
        self.menuStack.layer.masksToBounds = true
        
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tripsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let data = tripsArray[indexPath.row]
        
        if indexPath.row > 0 {
            let customCell = self.tripsCellView.dequeueReusableCell(withIdentifier: TripsTVC.identifier) as! TripsTVC
            customCell.configure(with: data.type, roundtrip: data.roundtrip, departure: data.departure, arrival: data.arrival, from: data.from, to: data.to, vehicle: data.vehicle)
            customCell.dateFrom?.text = data.departure
            customCell.dateTo?.text = data.arrival
            customCell.tripInformation?.text = "\(data.from) to \(data.to) // \(data.to) to \(data.from)"
            return customCell
        }
        
        return cell
    }
    
    @IBAction func addTripButtonPressed(_ sender: UIButton) {
    }
    
    @IBAction func userAccountButtonPressed(_ sender: UIButton) {
    }
    
}
5
  • If you just want some test data in your array you can add it to the declaration but not the way you do it, instead something like var tripsArray: [UserTrip] = [UserTrip(type: "Tourism", roundtrip: "True", departure: "March 10, 2024", arrival: "March 13, 2024", from: "YYZ", to: "OPO", vehicle: "Air"), UserTrip(type ...<data for second object and so on] Commented Mar 20, 2024 at 12:13
  • Note that I took the liberty of slightly renaming your custom type so it's more like how types normally are named, starting with a capital letter and in singular form. I would also recommend you start using built in types for some of your properties like Bool and Date. Commented Mar 20, 2024 at 12:16
  • Now it is crashing. It is throwing: libc++abi: terminating due to uncaught exception of type NSException Commented Mar 20, 2024 at 12:24
  • Set the exception breakpoint to get more detailed information. And don’t create cells with the default initializer. Reuse them. And the for loop in cellForRow makes no sense at all. Commented Mar 20, 2024 at 13:23
  • I have now erased the for loop and went ahead with the comment below, but it still throws same error. Found the problem to be on customCell.configure Commented Mar 20, 2024 at 13:27

1 Answer 1

0

I tried your code in Xcode and this is what is working.

class TripsTVC: UITableViewCell {

   @IBOutlet weak var label: UILabel!

   override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
   }

   required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
   }

   func configure(with: String, roundtrip: String, departure: String, arrival: String, from: String, to: String, vehicle: String) {
       label.text = with
   }
}

Make sure your label is connected in interface builder. There is no need to give any cell identifier. This works

self.tripsCellView.register(UINib(nibName: "TripsTVC", bundle: nil), forCellReuseIdentifier: String(describing: TripsTVC.self))

Here is the delegate method implementation

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let customCell = tableView.dequeueReusableCell(withIdentifier: String(describing: TripsTVC.self), for: indexPath) as! TripsTVC
    customCell.configure(with: "Tourism", roundtrip: "True", departure: "March 10, 2024", arrival: "March 23, 2024", from: "YYZ", to: "OPO", vehicle: "Air")
    return customCell
}

Make sure the connections in interface builder are accurate. The Custom Cell View should have the class TripsTVC and not the File Owner.

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

Funny thing, this has worked very well. In a way it answered what I needed, thank you! On the other hand, is only displaying half of the information, like the other labels are hidden. I printed them and it is showing well, so I am not totally sure why they are not rendering on the cell, but I am sure I will get there :)
Did you add proper constraints in the nib file for the other labels.
I did. For some reason xcode is ignoring the constraints and adjusting the size to be smaller than what I have set up. I was able to correctly display my content by programatically set rowHeight for the cell. Now, for some reason, it loads everything, but it also creates a gap between top view to cell of the same size as the cell itself. Is like I have two cells, but one is completely blank.
I found out that the code is working, but only retrieving the first class values from the array and not the other ones. If I add three different objects for example (all different inputs), xcode shows 4 cells, one white, and 3 with the exact same information as the others.
The one white cell might be the header/footer, try removing that.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.