Customise static tableview Header - Swift - ios

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
}

Related

UITableView stops scrolling after sometime

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

How to use a fixed cell in table and then a list of item below that?

I am using below code for one fixed cell at the top and then list of items in below in a single tableview, I am able to load the data from firestore database, but the first item in from the database is not shown, it is kind of hidden behind the fixed "detailscell", rest the fixed cell and all other items from the database shows up, how to fix that?
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// print(posts)
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 && details1.count > 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "detailsCell") as! DetailsCellInHomeScreen
cell.set(details: details1[indexPath.row])
return cell
} else if posts.count > (indexPath.row - 1) {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row - 1])
return cell
} else {
return UITableViewCell()
}
}
TableView has a function like below:
// MARK: - Headers and Footers
extension MyTableViewController {
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return MyCustomView()
}
}
You can use this function to return any view you want as a section header. Also note that sectionHeader views are sticky in default style tableView (not grouped style!). So you can use this as a advantage.
There are many tutorials like this one on the internet to follow and learn how to build a custom section section header for UITableView
You should add header on the table view:
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// print(posts)
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row - 1])
return cell
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: tableView.frame.width, height: 50))
let label = UILabel()
label.frame = CGRect.init(x: 5, y: 5, width: headerView.frame.width-10, height: headerView.frame.height-10)
label.text = "A Label on detailsCell"
headerView.addSubview(label)
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
if the tableView has several section you can realize the section with section: Int object
tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? uses for create the header view and tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat uses for set header height

How to remove the separator between the header and the first row in a grouped tableView

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:

How to make final footer in UITableView?

I tried to make a Footer in UITableView like in iOS app "Contacts".
I have simple tableView with simple array:
items = ["aa", "bb", "cc", "dd"]
I want to make empty space under last cell.
I tried to add this cellForRowAt:
if indexPath.row == self.converterItems.count-1 {
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0)}
But it delete separator only for one cell.
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
var header :UITableViewHeaderFooterView = UITableViewHeaderFooterView()
header.contentView.backgroundColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1)
return header
}
This method looks good, but it lost separator below last cell...
You should create a UIView and assign it to your table's footer view
myTableView.tableFooterView = createTableFooterView()
func createTableFooterView() -> UIView {
let footerView = UIView()
...
...
...
return footerView
}
To make the table endless. You'd better set UITableViewStyle.grouped
let tableView = UITableView(frame: CGRect.zero, style: .grouped)
And Then:
extension ViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return [].count// your array
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "", for: indexPath)
// your cell
// yourIdentifier, and you should register cell Identifier for tableView at first
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ""
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "83 KOH"
}
}

How to freeze a tableView cell in swift?

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
}

Resources