I have spent an hour trying to figure out what I'm doing wrong but no success. below is the code and an image of the result. All the rows appear one on top of the other in the first row of the table. and the row does not expand the width of the table as I have set it in the constraints. What am I doing wrong? Thank you. The table view class:
class TableViewListType: UITableView {
override init(frame: CGRect, style: UITableView.Style) {
super.init(frame: frame, style: style)
translatesAutoresizingMaskIntoConstraints = false
allowsSelection = true
allowsMultipleSelection = false
allowsSelectionDuringEditing = true
allowsMultipleSelectionDuringEditing = true
dragInteractionEnabled = false
backgroundColor = .clear
separatorColor = .white
separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
indicatorStyle = .white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The row classes for the table view:
class SuperRowForProfileAttributesTable: UITableViewCell {
//MARK: - Properties.
internal let firstLabel: LabelForRowInList = {
let label = LabelForRowInList(frame: .zero)
return label
}()
internal let secondLabel: LabelForRowInList = {
let label = LabelForRowInList(frame: .zero)
return label
}()
internal let thirdLabel: LabelForRowInList = {
let label = LabelForRowInList(frame: .zero)
return label
}()
internal let fourthLabel: LabelForRowInList = {
let label = LabelForRowInList(frame: .zero)
return label
}()
//MARK: - Init.
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
translatesAutoresizingMaskIntoConstraints = false
clipsToBounds = true
backgroundColor = .clear
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: - Functions.
internal func setupViews() {
addSubview(firstLabel)
addSubview(secondLabel)
addSubview(thirdLabel)
addSubview(fourthLabel)
let firstConstraints = [
firstLabel.topAnchor.constraint(equalTo: topAnchor),
firstLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
firstLabel.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1/3),
firstLabel.widthAnchor.constraint(equalTo: widthAnchor)
]
NSLayoutConstraint.activate(firstConstraints)
let secondConstraints = [
secondLabel.topAnchor.constraint(equalTo: firstLabel.bottomAnchor),
secondLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
secondLabel.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1/3),
secondLabel.widthAnchor.constraint(equalTo: widthAnchor)
]
NSLayoutConstraint.activate(secondConstraints)
let thirdConstraints = [
thirdLabel.topAnchor.constraint(equalTo: secondLabel.bottomAnchor),
thirdLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
thirdLabel.trailingAnchor.constraint(equalTo: centerXAnchor),
thirdLabel.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1/3),
]
NSLayoutConstraint.activate(thirdConstraints)
let fourthConstraints = [
fourthLabel.topAnchor.constraint(equalTo: secondLabel.bottomAnchor),
fourthLabel.leadingAnchor.constraint(equalTo: centerXAnchor),
fourthLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
fourthLabel.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1/3)
]
NSLayoutConstraint.activate(fourthConstraints)
}
}
class RowForExperienceInProfileTable: SuperRowForProfileAttributesTable {
//MARK: - Properties.
internal var valueForExperienceRow: ExperienceModelForProfileAttributes! {
didSet {
firstLabel.text = valueForExperienceRow.jobTitle
secondLabel.text = valueForExperienceRow.companyName
thirdLabel.text = valueForExperienceRow.startedWork
fourthLabel.text = valueForExperienceRow.finishedWork
}
}
}
class RowForSkillInProfileTable: SuperRowForProfileAttributesTable {
//MARK: - Properties.
internal var valueForSkillRow: SkillsModelForProfileAttributes! {
didSet {
firstLabel.text = valueForSkillRow.skill
}
}
//MARK: - Init.
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setupViews() {
addSubview(firstLabel)
let firstConstraints = [
firstLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
firstLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
firstLabel.widthAnchor.constraint(equalTo: widthAnchor, constant: 0),
firstLabel.heightAnchor.constraint(equalTo: heightAnchor, constant: 0)
]
NSLayoutConstraint.activate(firstConstraints)
}
}
class RowForEducationInProfileTable: SuperRowForProfileAttributesTable {
//MARK: - Properties.
internal var valueForEducationRow: EducationModelForProfileAttributes! {
didSet {
firstLabel.text = valueForEducationRow.institutionName
secondLabel.text = valueForEducationRow.degreeName
thirdLabel.text = valueForEducationRow.startedStudy
fourthLabel.text = valueForEducationRow.finishedStudy
}
}
}
The VC:
fileprivate var experienceForProfile = [ExperienceModelForProfileAttributes(jobTitle: "Tester", companyName: "Testing Company", startedWork: "May 2019", finishedWork: "October 2019"), ExperienceModelForProfileAttributes(jobTitle: "Welder", companyName: "Welding Company", startedWork: "January 2018", finishedWork: "May 2020")]
fileprivate var skillsForProfile = [SkillsModelForProfileAttributes]()
fileprivate var educationForProfile = [EducationModelForProfileAttributes]()
fileprivate lazy var tableForAttributes: TableViewListType = {
let table = TableViewListType(frame: .zero, style: .plain)
table.delegate = self
table.dataSource = self
return table
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.isHidden = true
tableForAttributes.register(RowForExperienceInProfileTable.self, forCellReuseIdentifier: firstIDForTable)
tableForAttributes.register(RowForSkillInProfileTable.self, forCellReuseIdentifier: secondIDForTable)
tableForAttributes.register(RowForEducationInProfileTable.self, forCellReuseIdentifier: thirdIDForTable)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var numberOfRows = 0
switch selectedMimicIndex {
case 0: numberOfRows = experienceForProfile.count
case 1: numberOfRows = skillsForProfile.count
case 2: numberOfRows = educationForProfile.count
default: print("nu such rows for attributes table in own profile")
}
return numberOfRows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch selectedMimicIndex {
case 0: let cell = tableView.dequeueReusableCell(withIdentifier: firstIDForTable, for: indexPath) as! RowForExperienceInProfileTable
cell.valueForExperienceRow = experienceForProfile[indexPath.row]
return cell
case 1: let cell = tableView.dequeueReusableCell(withIdentifier: secondIDForTable, for: indexPath) as! RowForSkillInProfileTable
cell.valueForSkillRow = skillsForProfile[indexPath.row]
return cell
case 2: let cell = tableView.dequeueReusableCell(withIdentifier: thirdIDForTable, for: indexPath) as! RowForEducationInProfileTable
cell.valueForEducationRow = educationForProfile[indexPath.row]
return cell
default: return UITableViewCell()
}
}
The selectedMimicIndex value is changed the didSelectItem() function of the collection view that I have; a cv that controls what cells the table displays. reloadData() is called here after the Int value is changed when the user changes the selected cv cell.
Also notice that the second row is much taller that it should be; ignores the height that I have specified.
For every label you need to set and add it to contentView
firstLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(firstLabel)
also the most bottom label to bottom of cell
fourthLabel.bottomAnchor.constraint(equalTo:self.contentView.bottomAnchor, constant:-20)