Created
May 15, 2023 05:38
-
-
Save djryanash/b3d0f360c50b020d82119316b47a766f to your computer and use it in GitHub Desktop.
Generic UITableView with Headers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ViewController: UIViewController { | |
var hasSearched: Bool = false | |
let peopleArray = [ | |
//["primaryImage", "personNext", "personJobTitle", "selectedImage", "section"], | |
["dollarsign.circle", "Ben Shapiro", "Accounts Manager", "dollarsign.circle.fill", "Core Team"], | |
["hammer.circle", "Robert Bokelman", "Operations Manager", "hammer.circle.fill", "Supplemental Team"], | |
["phone.connection", "Sandra Berman", "External Comms", "phone.connection.fill", "Supplemental Team"], | |
["key", "Nicolas Sarcozy", "President", "key.fill", "Core Team"], | |
["person", "Hillary Tate", "Marketing Manager", "person.fill", "Core Team"], | |
["paperplane", "Florence Wong", "Design and Execution", "paperplane.fill", "Core Team"], | |
["doc.badge.gearshape", "Indira Mohamed", "Research and Development", "doc.badge.gearshape.fill", "Core Team"], | |
["person.3", "Philipous Angelos", "International Relations", "person.3.fill", "Core Team"], | |
["alarm.waves.left.and.right", "Simon Graham", "Sales Manager", "alarm.waves.left.and.right.fill", "Core Team"], | |
["cloud.rain", "Tamara Westinghouse", "Environmental Impact", "cloud.rain.fill", "Supplemental Team"], | |
["baseball", "personNext", "personJobTitle", "baseball.fill", "section"], | |
["graduationcap", "personNext", "personJobTitle", "selectedImage", "graduationcap.fill"], | |
["trophy", "personNext", "personJobTitle", "selectedImage", "trophy.fill"], | |
["megaphone", "Forrest Gump", "personJobTitle", "selectedImage", "megaphone.fill"], | |
] | |
let sectionsArray = ["Core Team", "Supplemental Team"] | |
let tableView: UITableView = { | |
let tableView = UITableView() | |
tableView.translatesAutoresizingMaskIntoConstraints = false | |
tableView.backgroundView = UIView(frame: tableView.bounds) | |
tableView.backgroundView?.backgroundColor = .systemGray5 | |
tableView.allowsMultipleSelection = true | |
tableView.layer.cornerRadius = 20 | |
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") | |
tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "header") | |
return tableView }() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.view.backgroundColor = .systemGray6 | |
self.tableView.dataSource = self | |
self.view.addSubview(tableView) | |
self.tableView.delegate = self | |
self.tableViewConfigure() } | |
private func tableViewConfigure() { | |
self.tableView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true | |
self.tableView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true | |
self.tableView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true | |
self.tableView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true } | |
override func viewDidLayoutSubviews() { | |
if let rowHeight = self.tableView.cellForRow(at: [0,0])?.contentView.frame.height { | |
let numberOfRows = self.tableView.numberOfRows(inSection: 0) | |
self.tableView.heightAnchor.constraint(equalToConstant: CGFloat(rowHeight) * CGFloat(numberOfRows)) | |
.isActive = true | |
self.tableView.isScrollEnabled = false } | |
else { self.tableView.heightAnchor.constraint(equalToConstant: 540).isActive = true } } | |
func getSections(with array: [[String]]) -> [String] { | |
var sections: [String] = [] | |
for i in 0..<peopleArray.count { | |
if !sections.contains(peopleArray[i].last!) { | |
sections.append(peopleArray[i].last!) } } | |
return sections } | |
func getRowsInSections(with array: [[String]]) { | |
if !hasSearched { | |
var coreTeam = 0 | |
var supTeam = 0 | |
for item in array { | |
if item.last!.contains("Supplemental Team") { supTeam += 1 } | |
else { coreTeam += 1 } } } | |
hasSearched = true } | |
func setCell(with cell: UITableViewCell, cellForRowAt indexPath: IndexPath, column: Int) -> UITableViewCell? { | |
let sectionName = getSections(with: peopleArray)[indexPath.section] | |
let sectionItems = peopleArray.filter { $0.last == sectionName } | |
let item = sectionItems[indexPath.row] | |
var content = cell.defaultContentConfiguration() | |
content.image = UIImage(systemName: item[column]) | |
content.text = item[1] | |
content.secondaryText = item[2] | |
cell.contentConfiguration = content | |
return cell } | |
func checkMemoryUsage<R>(_ thingToCheck: R, name: String = #function) { | |
// You can pass in almost anything - a variable/constant/struct/class/function etc. | |
let size = MemoryLayout.size(ofValue: thingToCheck) | |
let stride = MemoryLayout.stride(ofValue: thingToCheck) | |
let alignment = MemoryLayout.alignment(ofValue: thingToCheck) | |
print("\(name).size: \(size)") | |
print("\(#function)).stride: \(stride)") | |
print("\(type(of: thingToCheck)).alignment: \(alignment)") } | |
} | |
extension ViewController: UITableViewDataSource, UITableViewDelegate { | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
var sections = self.getSections(with: peopleArray ) | |
if section < sections.count { | |
let sectionName = sections[section] | |
return peopleArray.filter { $0.last == sectionName }.count } | |
return 0 } | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) | |
return setCell(with: cell, cellForRowAt: indexPath, column: 0) ?? UITableViewCell() } | |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
if tableView.cellForRow(at: indexPath)?.isSelected == true { | |
let cell = tableView.cellForRow(at: indexPath)! | |
cell.selectionStyle = .none | |
_ = setCell(with: cell, cellForRowAt: indexPath, column: 3) } } | |
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { | |
if tableView.cellForRow(at: indexPath)?.isSelected == false { | |
let cell = tableView.cellForRow(at: indexPath)! | |
_ = setCell(with: cell, cellForRowAt: indexPath, column: 0) } } | |
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { | |
return self.getSections(with: peopleArray)[section] } | |
func numberOfSections(in tableView: UITableView) -> Int { | |
self.getSections(with: peopleArray).count } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment