Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

UITableView is not displayed in programmatic UIKit ViewController

I’m using UIKit programmatically. I’ve got a UITableView working fine in another view controller, and I’ve largely copied the code I used there to this VC, and yet I get no errors and the UITableView is not displayed. I checked the Debug View Hierarchy and it isn’t present there either. I’m not sure if this is related, but upon launching the Debug View Hierarchy the following message is displayed repeatedly in the debug window:
[API] Failed to get renderer info (client=0x82b3d507) [0x5 (os/kern) failure]. My print statement inside numberOfRowsInSection does fire, but my print statement in cellForRowAt does not. WorkoutTemplate and its child structs are simple data structures with no logic. I have a static property on WorkoutTemplate that is used for dummy data when laying out the UI.

class CreateWorkoutVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var exerciseListing: UITableView!
    
    var workoutTemplate: WorkoutTemplate!
    
    init(workoutTemplate: WorkoutTemplate) {
        super.init(nibName: nil, bundle: nil)
        
        self.workoutTemplate = workoutTemplate

        configure()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemBackground
    }
    
    private func configure() {
        let padding: CGFloat = 20

        exerciseListing = UITableView(frame: view.frame)

        view.addSubview(exerciseListing)
        
        exerciseListing.register(UITableViewCell.self, forCellReuseIdentifier: "exercise")
        exerciseListing.rowHeight = 50
        exerciseListing.dataSource = self
        exerciseListing.delegate = self
        exerciseListing.translatesAutoresizingMaskIntoConstraints = false
        
        
        NSLayoutConstraint.activate([
            exerciseListing.topAnchor.constraint(equalTo: view.topAnchor, constant: padding),
            exerciseListing.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
            exerciseListing.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding)
        ])
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("In numberOfRowsInSection: \(workoutTemplate.exerciseSets.count)")
        return workoutTemplate.exerciseSets.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "exercise", for: indexPath)
        
        let cellLabel = getCellLabel(withText: workoutTemplate.exerciseSets[indexPath.row].exercise.exerciseName)
        print(workoutTemplate.exerciseSets[indexPath.row].exercise.exerciseName)
        cell.addSubview(cellLabel)
        
        let padding: CGFloat = 8
        
        NSLayoutConstraint.activate([
            cellLabel.centerYAnchor.constraint(equalTo: cell.centerYAnchor),
            cellLabel.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: padding),
            cellLabel.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -padding),
            cellLabel.heightAnchor.constraint(equalTo: cell.heightAnchor)
        ])
        
        cell.backgroundColor = .secondarySystemBackground
        
        return cell
    }
    
    func getCellLabel(withText labelText: String) -> UILabel {
        let cellLabel = UILabel(frame: .zero)
        cellLabel.text = labelText
        cellLabel.textColor = .label
        cellLabel.adjustsFontSizeToFitWidth = true
        cellLabel.minimumScaleFactor = 0.90
        cellLabel.lineBreakMode = .byTruncatingTail
        cellLabel.translatesAutoresizingMaskIntoConstraints = false
        
        cellLabel.textAlignment = .left
        cellLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        
        return cellLabel
    }
}

Data Structures:

struct WorkoutTemplate {
    let workoutName: String
    var exerciseSets: [ExerciseSet]
    
    mutating func addExerciseSet(exerciseSet: ExerciseSet) {
        exerciseSets.append(exerciseSet)
    }
    
    static let exampleWorkouts = [WorkoutTemplate(workoutName: "Upper Body 1", exerciseSets: [ExerciseSet(exercise: Exercise(exerciseId: UUID(), exerciseName: "Bench Press"), sets: 3, targetReps: 8, targetRPE: 8, restPeriod: 2), ExerciseSet(exercise: Exercise(exerciseId: UUID(), exerciseName: "T-Bar Row"), sets: 3, targetReps: 8, targetRPE: 8, restPeriod: 3)]), WorkoutTemplate(workoutName: "Lower Body 1", exerciseSets: [ExerciseSet(exercise: Exercise(exerciseId: UUID(), exerciseName: "Hack Squats"), sets: 3, targetReps: 8, targetRPE: 8, restPeriod: 2), ExerciseSet(exercise: Exercise(exerciseId: UUID(), exerciseName: "Leg Ext"), sets: 3, targetReps: 8, targetRPE: 8, restPeriod: 3)])]
}

struct ExerciseSet {
    let exercise: Exercise
    let sets: Int
    let targetReps: Int
    let targetRPE: Int
    let restPeriod: Int
}

struct Exercise {
    let exerciseId: UUID
    let exerciseName: String
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You said:

I checked the Debug View Hierarchy and it isn’t present there either.

You checked in the graphical representation? Or in the hierarchy in the panel on the left? I ask because you do not appear to ever set the bottom constraint, so its height could be anything (even zero). And that would cause numberOfRowsInSection to be called, but cellForRowAt not to be called.

Bottom line, the table view was zero height, you wouldn’t see it in that wireframe (or it would appear to be a horizontal line). That’s why I advise navigating through the view hierarchy in the panel on the left, to find the tableview. The wireframe is great at debugging placement of views that you can see, but zero height views are harder to analyzer in there.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading