I am relatively new to UIKit with Swift. Currently, I am trying to make a simple UITableView containing a few UILabels for each cell (purely programmatically), although I have been having a lot of trouble trying to do this. My code is below:
import UIKit
class SettingsVC: UIViewController {
var settingsTableView = UITableView(frame: .zero, style: .insetGrouped)
override func viewDidLoad() {
super.viewDidLoad()
createTableView()
}
func createTableView() {
view.addSubview(settingsTableView)
setTableViewDelegates()
settingsTableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
settingsTableView.topAnchor.constraint(equalTo: view.topAnchor),
settingsTableView.leftAnchor.constraint(equalTo: view.leftAnchor),
settingsTableView.rightAnchor.constraint(equalTo: view.rightAnchor),
settingsTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
func setTableViewDelegates() {
settingsTableView.delegate = self
settingsTableView.dataSource = self
}
}
extension SettingsVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
}
This is currently what shows up in the Simulator.
This is what I would like to see.
How can I go about changing my preexisting code to get the end result I'm seeking? I have a feeling it has something to do about my delegate or data source, but no matter what I try, I seem to always get lost. Any help would be greatly appreciated.
CodePudding user response:
You need to make a custom cell class first
class CustomTableViewCell: UITableViewCell
make sure to give your custom cell the reuseIdentifier. For example,
class CustomTableViewCell: UITableViewCell {
static let reuseIdentifier: "CustomTableViewCell"
}
and inside that cell class, configure your desired label just like you did with settingsTableView
in SettingsVC
and return your CustomTableViewCell
in the cellForRowAt
function in SettingsVC
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.reuseIdentifier) as? CustomTableViewCell else {
print("Cannot find CustomTableViewCell")
return UITableViewCell()
}
return cell
}
CodePudding user response:
You're correct about missing the data source. you will have to declare your data source. I have refactored a bit of your code as below
import UIKit
class SettingsVC: UIViewController {
lazy var settingsTableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .insetGrouped)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.dataSource = self
return tableView
}()
//cell identifier
let cellIdentifier = "CellName"
//declare a datasource with your data
let myDataSource = ["Hello", "There", "My", "Friend"]
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
func setupView() {
view.addSubview(settingsTableView)
NSLayoutConstraint.activate([
settingsTableView.topAnchor.constraint(equalTo: view.topAnchor),
settingsTableView.leftAnchor.constraint(equalTo: view.leftAnchor),
settingsTableView.rightAnchor.constraint(equalTo: view.rightAnchor),
settingsTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
}
extension SettingsVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myDataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// This is how UITableView works:
// when the table becomes very long (let's say millions of cells)
// then the table will first allocate 4-5 cells to fill the iPhone's screen
// depend on the device's screen size, the number of cells will be different.
// as long as users scroll the table view down, the table view will re-use existing cells and update the values accordingly, there is no new memory allocated
// So the cell can be re-usable therefore you should call this func below to reduce memory warning issue
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
guard let myCell = cell else {
return UITableViewCell()
}
let myText = myDataSource[indexPath.row]
myCell.textLabel?.text = myText
return myCell
}
}