I using standard iOS UITableView loaded with data from a local database. I have implemented the delegates and datasource and registered my UITableView cell and header and everything looks fine. However after scrolling for couple of seconds, the tableview doesn't scroll again, this happens quickly if I scroll/swing very fast, the table view would just not responding to any touch event, no scroll, no cell selection. I don't know what am doing wrong. NB: There is no new data fetch so I don't reload the tableView data once initial data is loaded. This is my datasource class: TableCell is custom UITableViewCell while HeaderCell is custom UITableViewHeaderFooterView
func registerCells(tableView: UITableView) {
tableView.register(UINib.init(nibName: tableCell, bundle: nil), forCellReuseIdentifier: tableCell)
tableView.register(UINib(nibName: headerCell, bundle: nil), forHeaderFooterViewReuseIdentifier: headerCell)
print("\(sourceTag) register cells")
}
func numberOfSections(in tableView: UITableView) -> Int {
return viewModel.getNumberSections()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.viewModel.getNumberRowsInSection(section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = viewModel.dataValues[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: tableCell, for: indexPath) as! TableCell
cell.selectionStyle = .none
let quote = data.quotes[indexPath.row]
cell.setupWithQuote(quote, withSelectionDelegate: quoteSelectionDelegate)
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let data = viewModel.dataValues[section]
let headerCell = tableView.dequeueReusableHeaderFooterView(withIdentifier: enquiryCell) as! HeaderCell
headerCell.setupData(data)
return headerCell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return 161.0
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//print("I'm scrolling!")
NSLog("I'm scrolling!")
}
#DonMag comment pointed me to the right direction. There was a delegate method which was vetted assigned multiple times which led to a cyclic issue and hence table views cell rendering issue
Related
I am trying to customize static UITableViewController section header with UITableViewCell.
I could successfully cusomise section header in dynamic tableView by using the below set of code,
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell")
headerCell?.textLabel?.text = "Section \(section + 1)"
headerCell?.textLabel?.textColor = UIColor.blue
return headerCell
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
But, couldn't work for static tableview.
How to customise section header with static tableView
The problem is you should return a UIView, not a UITableViewCell in viewForHeaderInSection method.
Also you should keep an instance of header cell for future use (like modifying its view)
Create a field in your TableViewController like this:
private var headerViewCell: UITableViewCell?
and then in the viewForHeaderInSection do this:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell")
headerCell?.textLabel?.text = "Section \(section + 1)"
headerCell?.textLabel?.textColor = UIColor.blue
self.headerViewCell = headerCell
return headerCell?.contentView
}
I think you should unwrap cell when using dequeueReusableCell.
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as! HeaderCell // here header cell is your cell's custom class
headerCell.textLabel.text = "Section \(section + 1)"
headerCell.textLabel.textColor = UIColor.blue
return headerCell
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
My custom cell don't appear in my table View and I didn't find anything to answer that.
Here's my storyboard that contains the TableView :
This is my listController :
extension MatchListViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MatchCell", for: indexPath) as? MatchTableViewCell else {
return UITableViewCell()
}
let match = matchArray[indexPath.row]
cell.configure(nomDuMatch: match.matchName, scoreFinal: match.finalScore)
return cell
}
}
(I've configured the dataSourceDelegate by storyboard)
the customCell identifier is correct and I really don't understand why nothing appears at launch..
Feel free to ask me more pictures / infos !
Edit :
This is the result :
You need to implement
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100 // or any value
}
or use automatic cell and set constraints properly in IB as it seems that you have a constraints problem and set this in viewDidLoad
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
I am creating a static tableView. My goal is to have a single view that displays a tableView with 3 rows (get support, send feedback, participation terms), and a header + footer.
Right now, it all works fine EXCEPT the fact that there are two extra separators (one between the header and the first cell and the other between the last cell and the footer) that I cannot seem to get rid of.
Here is my code:
final class viewController: UITableViewController {
private let headerContainer = UIView()
private let footerContainer = UIView()
private let tableData = ["Get Support", "Send Feedback", "Participation Terms"]
override func viewDidLoad() {
super.viewDidLoad()
setupHeaderAndFooter()
setupTableView()
}
func setupHeaderAndFooter() {
/* setup code here (not relevant to this question) */
func setupTableView() {
// reinitializing tableView so that we can change its style to grouped
tableView = UITableView(frame: CGRect.zero, style: .grouped)
tableView.delegate = self
tableView.separatorStyle = .singleLine
}
//MARK: UITableView Methods
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return headerContainer
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return footerContainer
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 200
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel!.text = tableData[indexPath.row]
return cell
}
}
One way to achieve this is don't use default separator provided by UITableView. and place one UILabel or UIView and set its background color to light gray and set its height=1 (As per your requirement), width (full tableview width or as per your requirement) and position at bottom of all you content inside cell, header or footer.
Ok here you go.
The easy trick is actually a one-liner and a self-explanatory:
self.tableView.separatorColor = self.tableView.backgroundColor
AFTER:
I hope this helps!
You have to set clipsToBounds to true on your header view.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = //Get your header here
header.clipsToBounds = true
return header
}
Before:
After:
I have a UITableView in a UIViewController nested in a UITabBarController that has multiple sections, each with a custom section header that is a subclass of a UIView. The UItableView has all the proper delegates and data sources set up in code and the storyboard.
The footer is explicitly set to 0 in code.
For whatever reason, it seems that the background (in red below) bleeds past each of the UITableViewCells in each section.
My UITableView currently looks like this:
My settings for the tableview in the storyboard looks like this:
and finally, here is the code that controls the tableView, written as extensions on the UITableView subclass:
extension TestViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 64
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 34
}
}
extension TestViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = TestHeaderView()
view.setLabelWithValues(valueType: "Example", amount: 1)
return view
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath) as! TestTableViewCell
cell.testLabel?.text = "example"
cell.testLabel2?.text = "example"
cell.testLabel3?.text = "example"
return cell
}
}
How do I prevent the background from going past each section of cells?
Figured it out:
Looks like I had to set the footer size to 0 (which then defaults to 1) in the storyboard size inspector column like so:
This will leave a single pixel width of footer, so switch the background color to whatever your cell is.
I want to freeze a tableView cell on top of screen, so that while scrolling, other cells move but the top cell stays on its place.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
cell. //I think it must be here
return cell
Thank you.
Use these methods to create tableview header and add any subviews in it.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = UIView.init()
header.backgroundColor = UIColor.gray
//Add subviews here
return header
}
try this:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 65
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = view as! UITableViewHeaderFooterView
header.textLabel?.textColor = UIColor.black
header.textLabel?.text="adadafaf"//ur data
}