Displaying a list is one of the most important layout tools needed for any programming. This is where UITableView comes to help so that structured and organized data can be rendered and by customizing the UITableViewCell you gain full control of the individual row layout.
In this example we will create a UITableView with auto layout so that when you switch between portrait and landscape modes it renders the screen properly. Also we will create a custom Cell View for displaying our company data in multiple sections and rows. We are just using a JSON data string for input but in reality most of the time this data will come from a Web Service request. |
|
UITableView Controller Source
import UIKit
struct Company: Codable {
var name: String
var employees: [Employee]
}
struct Employee: Codable {
var name: String
var image: String
var years: Int
var salary: Double
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private var myTableView: UITableView!
private var companies: [Company]!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Main View"
//get data for display, this can be WEB Service API as well
companies = getCompanyData()
myTableView = UITableView()
myTableView.register(MyTableViewCell.self, forCellReuseIdentifier: "MyCell")
myTableView.dataSource = self
myTableView.delegate = self
//for auto layout rendering
myTableView.translatesAutoresizingMaskIntoConstraints = false
//hide extra lines
myTableView.tableFooterView = UIView()
//add to layout
self.view.addSubview(myTableView)
//auto layout for the table view
let views = ["view": view!, "tableView" : myTableView]
var allConstraints: [NSLayoutConstraint] = []
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[tableView]|", options: [], metrics: nil, views: views as [String : Any])
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: nil, views: views as [String : Any])
NSLayoutConstraint.activate(allConstraints)
}
//when user taps on the row
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Company Selected: \(companies[indexPath.section].name)")
print("Employee Selected: \(companies[indexPath.section].employees[indexPath.row].name)")
}
//no of sections for the list
func numberOfSections(in tableView: UITableView) -> Int {
return companies.count
}
//section heading
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section < companies.count {
return companies[section].name
}
return nil
}
//number of rows for that section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return companies[section].employees.count
}
//render the cell and display data
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyTableViewCell
let formatter = NumberFormatter()
formatter.numberStyle = .currency
let employee = companies[indexPath.section].employees[indexPath.row]
cell.employeeImage.image = UIImage(named: employee.image)
cell.employeeName.text = "\(employee.name)"
cell.yearsInService.text = "\(employee.years) years in service"
cell.salary.text = formatter.string(from: NSNumber(value: employee.salary))
return cell
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
//get JSON data into object for display
func getCompanyData() -> [Company] {
var companies: [Company] = [Company]()
let myJsonData = """
[{
"name": "ABC Company",
"employees": [{
"years": 12,
"name": "Joe",
"image": "apple.png",
"salary": 110000
},
{
"years": 15,
"name": "John",
"image": "apple.png",
"salary": 150000
}
]
},
{
"name": "XYZ Company",
"employees": [{
"years": 22,
"name": "Jake",
"image": "apple.png",
"salary": 220000.5
}]
}
]
"""
//Decode JSON Data String to Swift Objects
if let jsonData = myJsonData.data(using: .utf8) {
let decoder = JSONDecoder()
do {
companies = try decoder.decode([Company].self, from: jsonData)
for company in companies {
print("===")
print(company.name)
for employee in company.employees {
print("---")
print(employee.name)
}
}
} catch {
//do nothing
}
}
return companies
}
}
Custom Cell View Source
import UIKit
class MyTableViewCell: UITableViewCell {
let employeeImage = UIImageView()
let employeeName = UILabel()
let yearsInService = UILabel()
let salary = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
employeeImage.translatesAutoresizingMaskIntoConstraints = false
employeeName.translatesAutoresizingMaskIntoConstraints = false
yearsInService.translatesAutoresizingMaskIntoConstraints = false
salary.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(employeeImage)
contentView.addSubview(employeeName)
contentView.addSubview(yearsInService)
contentView.addSubview(salary)
let views = [
"image" : employeeImage,
"name" : employeeName,
"years" : yearsInService,
"salary": salary,
]
var allConstraints: [NSLayoutConstraint] = []
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-[image(50)]", options: [], metrics: nil, views: views)
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:[salary]-|", options: [], metrics: nil, views: views)
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-[name]-[years]-|", options: [], metrics: nil, views: views)
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-[image(50)]-[name]-|", options: [], metrics: nil, views: views)
allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-[image]-[years]-[salary]-|", options: [], metrics: nil, views: views)
NSLayoutConstraint.activate(allConstraints)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
No comments:
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.