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.
Related
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
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 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
}
I want to implement UITableView inside UITableViewCell with dynamic height of cell according to inside UITableView content size. How can I implement this any suggestions?
I want layout something like this...
Code work:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let identifier = "OrderHistoryTVCell" let cell: OrderHistoryTVCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? OrderHistoryTVCell
let tableInnerContentSize = cell.tableInner.contentSize.height
let nn = cell.viewAfterTable.frame.height+tableInnerContentSize
return nn
}
use following:
#IBOutlet weak var tableView: UITableView! //connect the table view
//do following in viewDidLoad method
tableView.estimatedRowHeight = 100 //Your estimated height
tableView.rowHeight = UITableViewAutomaticDimension
Also set these two properties of UILable from Attributes inspector section of storyboard:
lines to 0
Line break to word wrap
or you can also set these properties from code:
self.lblxyz.numberOfLines = 0
self.lblxyz.lineBreakMode = .byWordWrapping
Note - Add constraint properly in table view cell.
You have to do something like this:
In ui Master-Item # is be your section header. So take UILabel and add it as a section header.
Your sub-item is the prtotype-cell cell which contains one label.
Constraints for label inside cell.
In your cell first add UIView with constraints as follows:
Top , Bottom , Leading, Bottom to superView as 0.
Now add label and give constraints as follow.
Top , Bottom , Leading, Bottom to UIView as 8.
Give height constraint as per your requirement.
Give height relationship from = to >=.
Set label property line to 0 from storyboard.
Implement this lines in
//MARK:- TableView
public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat{
return 60 // return header height
}
public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// return your section header i.e. master item label
}
public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat{
return 50;
}
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return UITableViewAutomaticDimension
}
public func numberOfSections(in tableView: UITableView) -> Int{
// return number of section i.e. total count of master item.
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
// returns number of cells in each section
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
// return your custom cell here
//eg:
// cell.labelFood.text = your data
}
NOTE Don't forget to bind delegate and dataSource of tableView.
use this code in viewDidLoad()
self.tableView.estimatedRowHeight = 350
self.tableView.rowHeight = UITableViewAutomaticDimension
Use this Delegate
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
self.tableView.estimatedRowHeight = 160
return UITableViewAutomaticDimension
}
Also set these two properties of UILable.
#IBOutlet weak var label: UILabel!
label.numberOfLines = 0