I know there are a lot of posts about it, but maybe in newest iOS there are some updates on this...
I think all of us had a task to create viewController that has a lot of content at the top, most of them are self-sizing, and at the very bottom it figures out that you need to show some tableView with many items...
The first solution that can be done is to use UIScrollView, and don't care about reusableCells at all.
The second is to use UITableView's headerView and adjust its height manually (or by calling systemLayoutSizeFittingSize:) each time when it is needed.
Maybe the third solution is to use UITableView and self-sized UIView separately, with having UIEdgeInsets on tableView. And depending on what object has higher "zIndex", it can bring problems with handling interactions...
The forth solution is to use whole content above the cell, like a separate cell. Not sure this is a good idea at all...
Question: Is there any new solution to this problem? I haven't dig into it for like 2 years... Maybe in new iOS there is something like reusableViews for UIScrollView... Of course, the goal is to have reusable cells, and header with using autolayout without necessity of updating its height manually...
I am guessing you are talking about section headers of table view here. If that is so you can absolutely use auto layout for section headers.
Use the below two code in viewDidLoad:
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 36;
Now in viewForHeaderInSection: try the below code just to get an idea how things are working out. Change it according to your requirement.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label: UILabel = {
let lb = UILabel()
lb.translatesAutoresizingMaskIntoConstraints = false
lb.text = "HEADER \(section) with a loooooooooooooooonnngngngngngngngng texxxxxxxxxxxxxxxxt"
lb.textColor = .black
lb.backgroundColor = .yellow
lb.numberOfLines = 0
return lb
}()
let header: UIView = {
let hd = UIView()
hd.backgroundColor = .blue
hd.addSubview(label)
label.leadingAnchor.constraint(equalTo: hd.leadingAnchor, constant: 8).isActive = true
label.topAnchor.constraint(equalTo: hd.topAnchor, constant: 8).isActive = true
label.trailingAnchor.constraint(equalTo: hd.trailingAnchor, constant: -8).isActive = true
label.bottomAnchor.constraint(equalTo: hd.bottomAnchor, constant: -8).isActive = true
return hd
}()
return header
}
I'm using XCode 10.3 and this is my solution worked with your second solution using table header view.
First, you would create a separating view with xib file, for example with a label inside. And you apply the constraints for this label, top, left, bottom, right to the cell's container view. And set numberOfLines = 0.
Update your awakeFromNib() function inside your view class.
override func awakeFromNib() {
super.awakeFromNib()
ourLabel.translatesAutoresizingMaskIntoConstraints = false
}
Second, on your viewController, setup your tableView:
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 64
Remember don't delegate this method:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
because we set the constraints of our view already.
Finally, you return it on the delegate method
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
the view for header.
let view = UINib(nibName: String(describing: SimpleHeaderTitleView.self), bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! SimpleHeaderTitleView
view.ourLabel.text = "Your longgggg text"
return view
Done! Check it works.
I like the way it's done here:
• If you want to set your tableview header height dynamically based on it's content, just call self.tableView.layoutTableFooterView() right after you have set your headerView as TableViewHeader (so after self.tableView.tableHeaderView = view )
• If you need to update your tableview header height on runtime, also call self.tableView.layoutTableFooterView() right after you have updated the values of your tableview header.
(This obviously also works with tableviewFooters, though, is not to be used for sectionHeaders/Footers)
extension UITableView {
//Variable-height UITableView tableHeaderView with autolayout
func layoutTableHeaderView() {
guard let headerView = self.tableHeaderView else { return }
headerView.translatesAutoresizingMaskIntoConstraints = false
let headerWidth = headerView.bounds.size.width
let temporaryWidthConstraint = headerView.widthAnchor.constraint(equalToConstant: headerWidth)
headerView.addConstraint(temporaryWidthConstraint)
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
let headerSize = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
let height = headerSize.height
var frame = headerView.frame
frame.size.height = height
headerView.frame = frame
self.tableHeaderView = headerView
headerView.removeConstraint(temporaryWidthConstraint)
headerView.translatesAutoresizingMaskIntoConstraints = true
}
}
source
Copied from useyourloaf.com
Swift 5.0
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let headerView = tableView.tableHeaderView else {return}
let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
if headerView.frame.size.height != size.height {
headerView.frame.size.height = size.height
tableView.tableHeaderView = headerView
tableView.layoutIfNeeded()
}
}
Step One :
From interface builder Drag a UIView and drop into
UItableView
This view will automatically act as a UITableView Header (Mind it not section Header)
. Suppose this the width of this view is 200 .If you run the UItableView This view will automatically appear as a Header .
Create a Outlet of this drag-drop View .
#property (weak, nonatomic) IBOutlet UIView *tableViewHeader; // height of this view is 200
Now my goal is increase the height of the table View header .
Step Two :
Add this method
- (void)viewDidLayoutSubviews
{
int increasedHeight = 100;
// set a frame of this view Like example
self.tableViewHeader.frame = CGRectMake(0, 0, self.view.frame.size.width , 200 + increasedHeight );
self.tableView.tableHeaderView = self.tableViewHeader;
}
Now you tableview header height will be 300 .
This is how i have approached it
Using tableview
I have created the UI For the header in XIB
Now in the following delegate method
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
}
I Create a UIView for the header and calculate the height based on the content and return the same.
Now i can return the same header view from the following delegate method
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
}
Based on the section i again create a view from xib and return that view from the method.
In my case i needed only one headerview for table so i kept 2 sections and returned the headerview for section one.
If you are using Interface Builder simply you check these buttons
You can do that in viewDidLayoutSubviews of the UIViewController that contains your UITableView:
#IBOutlet weak var tableView: UITableView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Resize header view with dynamic size in UITableView
guard let headerView = tableView.tableHeaderView else {
return
}
let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
if headerView.frame.height != size.height {
tableView.tableHeaderView?.frame = CGRect(
origin: headerView.frame.origin,
size: size
)
tableView.layoutIfNeeded()
}
}
Xcode 14 + Swift 5
This is how I made it.
First step - configuring of table view for dynamic height headers usage:
In viewViewDidLoad you need to add:
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 40
This also can be done in xib/storyboard where your tableView is located instead of configuring in code:
Second step - creation of header view:
You need to create custom view to use as table's header. For example view with label as a subview, pinned with constraints to superview. Any view that contains some subviews that could cause it to have different height. The main thing - you should set up content of header with constraints to make it resize itself.
Third step - configuration of tableView's delegate:
In your tableView delegate implement viewForHeaderInSection method and just return configured instance of your custom header view.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
IMPORTANT - heightForHeaderInSection method shouldn't be implemented, just don't add it.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
Related
I have a tableHeaderView that should be with dynamic height according to its content.
I tried use the systemLayoutSizeFitting & sizeToFit method in order to set new height for the table view, Unfortunately It's seems to be work well but not as I want (one of the dynamic UI get cropped). I tried to set the content compression resistance priority of the UIs that i want to be dynamic to (1000) but its dose not work as well.. every time at least one UI cropped.
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var podView: PodView!
#IBOutlet weak var postCaption: UILabel!
var pod: Pod!
override func viewDidLoad() {
super.viewDidLoad()
//set header view
podView.setPod(image: pod.image, title: pod.title, description: pod.description, viewWidth: UIScreen.main.bounds.width)
podView.sizeToFit()
postCaption.text = pod.description
postCaption.sizeToFit()
let height = tableView.tableHeaderView!.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
tableView.tableHeaderView!.frame.size.height = height
}
edit: constraint:
view constraint
label Constraint
For having TableHeaderView with dynamic height. Add following code to your viewController. It will work like charm.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
//Comparison necessary to avoid infinite loop
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
}
}
}
Note: Make sure your tableHeaderView is having proper AutoLayout Constraints to get proper height.
Try this steps for creating dynamic tableview header cell :-
1 - Add one UItableViewCell on tableview from storyboard
2 - Create tableView header UI as per your requirement.
3 - Create class as TableViewHeaderCell something according to your requirement what you want to show in header cell.
4 - Then in a ViewController class implement headerview delegate method.
/**
Tableview header method
*/
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
}
5 - In this method you want to create TableViewHeaderCell object and return cell content View like this.
/**
Table Header view cell implement and return cell content view when you create cell object with you identifier and cell name after that you have to mention height for header cell
*/
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell Identifier") as! CellName
return cell.contentView
}
6 - Implement Tableview header height method
/**
Here you can specify the height for tableview header which is actually your `TableViewHeader Cell height`
*/
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
//For eg
return 100
}
From this steps you can acheive dynamic Header view cell as well as footer view cell also, but for footer view cell implement Tableview footer view delegate methods.
Thank You,
I am creating a IOS app in swift and want to add spacing between cells like this
I would like to give space of each table view cell same like my attach image.
How I can do that? and Right now all cells are coming without any space.
swift3
you can try this in your class of tableView cell:
class cell: UITableViewCell{
override var frame: CGRect {
get {
return super.frame
}
set (newFrame) {
var frame = newFrame
frame.origin.y += 4
frame.size.height -= 2 * 5
super.frame = frame
}
}
}
From Storyboard, your view hierarchy should be like this. View CellContent (as highlighted) will contain all the components.
Give margin to View CellContent of 10px from top, bottom, leading & trailing from its superview.
Now, select the tblCell and change the background color.
Now run your project, make sure delegate and datasource are properly binded.
OUTPUT
NOTE: I just added 1 UILabel in View CellContent for dummy purpose.
Update: UIEdgeInsetsInsetRect method is replaced now you can do it like this
contentView.frame = contentView.frame.inset(by: margins)
Swift 4 answer:
in your custom cell class add this function
override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentView.frame = UIEdgeInsetsInsetRect(contentView.frame, margins)
}
You can change values as per your need
***** Note *****
calling super function
super.layoutSubviews()
is very important otherwise you will get into strange issues
If you are using UITableViewCell to achieve this kind of layout, there is no provision to provide spacing between UITableViewCells.
Here are the options you can choose:
Create a custom UIView within UITableViewCell with clear background, so that it appears like the spacing between cells.
You need to set the background as clear of: cell, content view.
You can use UICollectionView instead of UITableView. It is much more flexible and you can design it the way you want.
Let me know if you want any more details regarding this.
One simple way is collection view instead of table view and give cell spacing to collection view and use
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
let widthSize = collectionView.frame.size.width / 1
return CGSize(width: widthSize-2, height: widthSize+20)
}
And if you want tableview only then add background view as container view and set background color white and cell background color clear color set backround view of cell leading, trilling, bottom to 10
backgroundView.layer.cornerRadius = 2.0
backgroundView.layer.masksToBounds = false
backgroundView.layer.shadowColor = UIColor.black.withAlphaComponent(0.2).cgColor
Please try it. It is working fine for me.
You can use section instead of row.
You return array count in numberOfSectionsInTableView method and set 1 in numberOfRowsInSection delegate method
Use [array objectAtIndex:indexPath.section] in cellForRowAtIndexPath method.
Set the heightForHeaderInSection as 40 or according to your requirement.
Thanks,Hope it will helps to you
- Statically Set UITableViewCell Spacing - Swift 4 - Not Fully Tested.
Set your tableView Row height to whatever value you prefer.
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = <Your preferred cell size>
tableView.rowHeight = UITableViewAutomaticDimension
// make sure to set your TableView delegates
tableView.dataSource = self
tableView.delegate = self
}
extension YourClass : UITexFieldDelegate, UITextFieldDataSource {
//Now set your cells.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! UITableViewCell
//to help see the spacing.
cell.backgroundColor = .red
cell.textLabel?.text = "Cell"
return cell
}
//display 3 cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
//now lets insert a headerView to create the spacing we want. (This will also work for viewForHeaderInSection)
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//you can create your own custom view here
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 44) //size of a standard tableViewCell
//this will hide the headerView and match the tableView's background color.
view.backgroundColor = UIColor.clear
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
}
I have a UITableView that UITableViewCell has a dynamic UILabel which will be added based on data i get from the database.
I'm using something like
let testing = ["A", "B", "C", "D"] // This array is dynamic data
self.dictionaryTableView.estimatedRowHeight = 44
self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
var y = 0
for var i in 0..<self.testing.count {
let lbl = UILabel(frame: CGRect(x: 0, y: y, width: 50, height: 25))
lbl.text = self.testing[i]
lbl.numberOfLines = 0
cell.addSubview(lbl)
y += 20
}
return cell
}
But UITableViewCell height does not stretch automatically to display all content cell. Please help
Here is the result
EDIT I added constraint for the uilabel in UITableView cellForRowAtIndexPath, the constraints are working (I knew it when I expend the cell height), but cell height not automaticly strech out
var bottomAnchor: NSLayoutYAxisAnchor = NSLayoutYAxisAnchor()
for var i in 0..<self.testing.count {
let lbl = UILabel()
lbl.text = self.testing[i]
lbl.numberOfLines = 0
lbl.translatesAutoresizingMaskIntoConstraints = false
cell.addSubview(lbl)
lbl.leftAnchor.constraint(equalTo: cell.leftAnchor, constant: 16).isActive = true
lbl.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true
lbl.heightAnchor.constraint(equalToConstant: 25).isActive = true
if i == 0 {
lbl.topAnchor.constraint(equalTo: cell.topAnchor).isActive = true
} else {
lbl.topAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
bottomAnchor = lbl.bottomAnchor
}
return cell
Many thanks
There are two things that you need to fix in your implementation:
Create the layout of your cell before dequeueing it in tableView(_:, cellForRowAt:).
For efficiency reasons, table views reuse the same cells over and over again when the user scrolls. That's why you use this weird "dequeuing" function rather than simply instantiating a new cell.
let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
will always try to return a used cell that just scrolled out of the view. Only if there are no recycled cells available (for example when dequeueing the first couple of cells) the table view will create new instances of a cell.
The recycling of cells is the very reason why you should never create your cell's layout inside tableView(_:, cellForRowAt:), for example by adding a label. When the cell is being reused, another label will be added on top of the label that you added before and when it's being reused a second time, you'll end up with three overlapping labels etc.
The same applies to constraints. When you add constraints to a cell in tableView(_:, cellForRowAt:) without removing existing ones, more and more constraints will be added while the user is scrolling, most likely resulting in serious constraint conflicts.
Instead, setup your cell's layout before dequeueing it. There are several ways to achieve this:
If you use a UITableViewController inside a storyboard, you can create dynamic prototypes and lay out the cells directly in the storyboard. You could, for example, drag a label to a prototype cell there and create an outlet for it in a custom UITableViewCell subclass.
You can create a XIB file for your cell, open it in Interface Builder and create your layout there. Again, you need to create a UITableViewCell subclass with the appropriate outlets and associate it with your XIB file.
You can create a UITableViewCell subclass and set up your layout purely in code, for example inside the cell's initializer.
You need to use Auto Layout.
If you create your layout in Interface Builder, you just need to add the necessary constraints and you're good to go. If you create your layout in code, you need to set the translatesAutoresizingMaskIntoConstraints property to false for all views that you wish to constrain, for example:
lbl.translatesAutoresizingMaskIntoConstraints = false
In your particular layout, you need to constrain the label at the left, right, top and bottom with the corresponding edges of your cell's contentView.
If you don't know how to do that, please read Apple's Auto Layout Guide. (It's usually a better idea to do this in Interface Builder rather than in code.)
A very detailed description of how to use "Auto Layout in UITableView for dynamic cell layouts & variable row heights" can be found here.
used this code.
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
You can use UITableView section to render the data instead of adding the view programmatically. Here's the example:
class ViewController: UITableViewController {
private var dataSectionOne = ["Data 1", "Data 2"]
// This can be your dynamic data.
// Once the data changed, called tableView.reloadData() to update the view.
private var dataSectionTwo = ["A", "B", "C"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return dataSectionOne.count
} else if section == 1 {
return dataSectionTwo.count
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if indexPath.section == 0 {
cell.textLabel?.text = dataSectionOne[indexPath.row]
} else if indexPath.section == 1 {
cell.textLabel?.text = dataSectionTwo[indexPath.row]
}
return cell
}
}
The results:
I found the answers here
I added a constraint to my UITableViewCell bottom with the following code and it's working, but I don't know what exactly this line doing (I don't know the parameters too)
Could anyone help me explain this code
let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lbl, attribute: NSLayoutAttribute.bottomMargin, relatedBy: NSLayoutRelation.equal, toItem: cell.contentView, attribute: NSLayoutAttribute.bottomMargin, multiplier: 1, constant: -8)
cell.contentView.addConstraint(bottomSpaceConstraint)
I have a tableView header. I put a view and several items in. However, when a button is tapped, some objects in the view are hidden so that the view doesn't contain it as well anymore:
How would I change the view height to match the items in the view?
Implementing this delegate function can help you...
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return Your_View.frame.height Or Others
}
Try dynamically sizing the headerview by overriding viewDidLayoutSubviews() and see if that works :)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Dynamic sizing for the header view
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
// If we don't have this check, viewDidLayoutSubviews() will get
// repeatedly, causing the app to hang.
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
}
}
}
You need to set the sectionHeaderHeight property in viewDidLoad. You will need to have tableView reference if you are using storyboard unless if your ViewCOntroller is of type TableViewController then just use below code.
# Set the Header height to 50 points
tableView.sectionHeaderHeight = 50
I have this table view which works how i want it to however i have a problem where the footer overlap the cells in the table view as seen in
How can i prevent this? This is my code for the footer
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
// self.myTableView.tableFooterView = footerView;
let sectionString = Array(foodArray.keys)[section]
for value in caloriesArray[sectionString]! {
calories += value
}
totalCalories += calories
print(calories)
print(totalCalories)
let label = UILabel(frame: CGRectMake(footerView.frame.origin.x - 15, footerView.frame.origin.y, footerView.frame.size.width, 20))
label.textAlignment = NSTextAlignment.Right
label.text = "Total Calories: \(calories) "
footerView.addSubview(label)
calories = 0
return footerView
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 20.0
}
#IBAction func addFoodTapped(sender: AnyObject) {
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let sectionString = Array(foodArray.keys)[indexPath.section]
foodArray[sectionString]?.removeAtIndex(indexPath.row)
caloriesArray[sectionString]?.removeAtIndex(indexPath.row)
print(foodArray)
viewDidAppear(true)
}
You can do that, Just make Style Grouped as shown below:
Just add some padding to the bottom of the content so that it doesn't overlap with the footer:
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, FOOTER_HEIGHT, 0)
I know this is an old thread, so this is more so for others that encountered this (like myself).
The floating section footer is default behavior from my understanding. There are a couple of options that I can think of:
Provide your footer view with a background color (footerView.backgroundColor = UIColor.white) thus cleaning up the overlap.
or
Replace the section footer with a custom "Total Calories" cell that you add to the table after the last cell in that section, effectively acting like a footer cell.
Sorry for the delay. If you have modified the standard contentInsetAdjustmentBehavior of the tableView, you must adjust the tableView contentInset property to take into account the total height of the views at the bottom of the UITableView, like the tab bar. If contentInsetAdjustmentBehavior is set to "automatic" (or you didn't change the default value), then set the clipsToBounds property of your footer view to true so that its child views cannot be painted outside the footer view layer's frame. That should solve your issue.
Try to override this method
override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 44.0
}
Just set your label's background color to UIColor.white. and you are done !
label.backgroundColor = UIColor.white
Of course it overlaps. This is how footers and header work in UITableViews. You can set the footerView.backgroundColor to UIColor.gray, for example, to make it look better.