How to set clear background for UITableView Header with opaque body - ios

How do I make the background for a tableHeaderView clear, but keep the rest of the UITableView background opaque?
I'm using a transparent tableHeaderView for a paralax effect. The object behind the tableView is a longer than the clear tableHeaderView "window" so I can center the visible data. This works well for longer lists as I can use the tableView as a mask, but when I don't have enough cells in the table the background object displays below the cells.
Relevant code:
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor whiteColor];
UIView *tableHeaderView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, 320.0, 250.0)];
tableHeaderView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = tableHeaderView;
I've tried setting a background color for the tableView, but that makes the whole UITableView opaque (including the tableHeaderView), removing the "window" I have at the top.
Any ideas on how I can keep my transparent tableHeaderView while setting the body of the UITableView opaque?
Thanks!

After a couple days I was able to figure it out. The premise of the solution is to add a subview to the backgroundView of your table and change the subview's frame as you scroll.
The relevant code in viewDidLoad:
...
// Create the UIView that will become the tableView backgroundView
UIView *tableViewBackground = [[UIView alloc] initWithFrame:self.tableView.frame];
tableViewBackground.backgroundColor = [UIColor clearColor];
// Create the opaque backgroundView and set the frame so that it starts below the headerView
partialBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 250, 320.0, self.view.frame.size.height)];
partialBackgroundView.backgroundColor = [UIColor redColor];
// Add the partial background to the main background view and apply it to the tableView
[tableViewBackground addSubview:solidTableBodyBackgroundView];
self.tableView.backgroundView = tableViewBackground;
...
And then as you scroll, you can update the "visible window" in scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat scrollOffset = scrollView.contentOffset.y;
partialBackgroundView.frame = CGRectMake(0, 250 - scrollOffset, 320, self.view.frame.size.height);
// Other parallax code for scrolling
}
There may be better ways of doing this, but I found this to be pretty simple and it worked well.

A simpler way of doing the accepted answer for multiple sections
// Set the view for each cell with a clear color
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)]; //
view.backgroundColor = [UIColor clearColor];
return view;
}
// Set the height of your desired header
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 10;
}

Here's a super late but quick and simple answer to this if like me you're returning a subclass of UITableViewHeaderFooterView as header view in your viewForHeaderInSection delegate method.
Setting myHeaderView.backgroundColor = UIColor.clear not helping you?
Try setting myHeaderView.layer.backgroundColor = UIColor.clear.cgColor instead.

Unless I'm misunderstanding something, you should be able to do this in two steps:
You will need to make the cells in your table opaque. Leave the tableView's background color set to [UIColor clearColor], and same goes for the views for your table header (and section headers if that applies).
Then take your table footer view (tableFooterView property of the UITableView), make it opaque, and make it very tall. When you only have a few cells in the table, the table footer will take up the rest of the screen.
Again, I might be misunderstanding something, but give that a go and see what you get. Good luck!

Swift-5, Transparent Section Header
Add a view and set its background as transparent
then return this view in ViewForSectionHeader method in tableView
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return viewForSection
}

Related

UITableView headerView scroll offset

I'm facing a problem with UITableView and it's property tableHeaderView.
I want to have the tableHeaderView to behave like UISearchBar, i.e. the content offset should be the of tableHeaderView.
Setting contentOffset, etc. didn't help when the table view wouldn't fill the view's frame.
Here's a screenshot of the current behavior:
(source: tubtub.de)
And how I'd like it to have:
(source: tubtub.de)
I'm inserting the headerView in viewDidLoad as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
}
Any help or hint is highly appreciated. Thanks!
EDIT: I made it working by utilizing UIScrollViewDelegate and subclassing UITableView. Check it out on the github repo provided.
You can use setContentOffset: by headerView height.
This contentOffset will only happen when you have enough number of data to be off by your headerView height. i.e) If tableView is not scrollable because you have only few data like one in your screenshot, the headerView is still visible. However if you have lots of number of data that can't not be displayed in the screen it will have contentOffset.
Try this with 20 rows. You will see what I mean.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
[self.tableView setContentOffset:CGPointMake(0, 44)];
With only 3 rows, this contentOffset won't work and it might be desired behavior in your case because you don't want to hide the searchBar when you have extra space to display.
I came up with implementing my own solution.
I utilize UIScrollViewDelegate and came up with a subclass of UITableView for calculating the contentSize dynamically.
Take a look at the github repo here.
I would double check the frame for the table itself. By setting the headerView's frame to start at 0,0, you are specifying that it should have its origin in the top left of the the view that is designated for the table.

How to make UITableView looks like this

is it possible to make a distance between cells like that in standard UITableView? There is no options to make separator bigger. Also this distance from right and left.
you can do this by set your cell background to whatever background you want (let's say gray in this case) and in the cell, add a white uiview with left, right, and bottom margin like this:
Then go to your table view, set the separator as none
and one last step, set the background of your table view to the same gray background as your cell.
Then you don't have to do anything particularly in your code besides simply initial your table cell based on the custom nib file (i assume you want to do this anyway).
If you prefer to construct your cell in codes, you can use the same logic.
in method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
cell.backgroundColor = [UIColor whiteColor];
// This will create a line of 3 pixels that will be separating the cells
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,3)];
separator.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separator];
// and if you want the border do left and right add:
UIView *separatorRx = [[UIView alloc] initWithFrame:CGRectMake(318,0,2,cell.frame.size.height)];
separatorRx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorRx];
UIView *separatorSx = [[UIView alloc] initWithFrame:CGRectMake(0,0,2,cell.frame.size.height)];
separatorSx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorSx];
return cell;
}
One way would be to set the backgroundView of the UITableViewCell to an UIImageView containing this white box on that gray background
You have to make a subclass of UITableViewCell. In your own subclass you may make everything you dream about! So, you need to add UIView with whiteColor background and margins as subview on your custom UITableViewCell.
There is not padding option in UITableView. You can either add a UIView in your UITableViewCell which will contains all the cell subviews, and change it's frame to create a padding right in the cell.
I suggest you to use UICollectionView instead, you can easily set the space between cells using a layout. If the cell is smaller than the actual collection View, then it's automatically centered.

UITableView: the proper way to display a separator for the last cell

The question is what's the right-most way to display a separator in the last cell in a table/section.
Basically this is what I am after.
This is from the native music app, which makes me think that it should be possible to achieve just by means of UITableView, they would not be using some private API for cell separators, right?
I know you can get away without using actual separators, but adding one pixel line in the bottom of the cell. But I'm not a fan of this approach because
When a cell is selected/highlighted its separator and the separator of the previous cell are automatically hidden (see the second screenshot with "You've got to be crazy" selected). And this is
something I want UITableView to handle instead of doing myself if I use one-pixel line
(which is especially handy when cell separators do not extend all
the way to the edge of the table view, separators and selected cell background do not look nice together).
I would like to keep my cells as flat as possible for scrolling performance.
Also there is something in UITableView reference that makes me think that there is an easy way to get what I want:
In iOS 7 and later, cell separators do not extend all the way to the
edge of the table view. This property sets the default inset for all
cells in the table, much like rowHeight sets the default height for
cells. It is also used for managing the “extra” separators drawn at
the bottom of plain style tables.
Does somebody know how exactly to use these “extra” separators drawn at the bottom of plain style tables? Because this is exactly what I need.
I thought assigning separatorInsetto the UITableView, not UITableViewCell would do the trick, but it does not, the last cell is still missing its separator.
Right now I only see one option: to have a custom section footer to mimic the separator for the last cell. And this is not good, especially if you want to have an actual section footer using tableView:titleForFooterInSection: method.
This worked flawlessly for me to add a separator to the last cell. have fun!
self.tableView.tableFooterView = [[UIView alloc] init];
When you add headerView or footerView to your TableView, last separator line will disappear.
Example below will let you make workaround for showing separator on the last cell. The only thing you have to implement more is to make this separator disappearing after selecting cell, so behavior is the same like in the rest of cells.
For Swift 4.0
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let result = UIView()
// recreate insets from existing ones in the table view
let insets = tableView.separatorInset
let width = tableView.bounds.width - insets.left - insets.right
let sepFrame = CGRect(x: insets.left, y: -0.5, width: width, height: 0.5)
// create layer with separator, setting color
let sep = CALayer()
sep.frame = sepFrame
sep.backgroundColor = tableView.separatorColor?.cgColor
result.layer.addSublayer(sep)
return result
}
I just found something that works for me. In a few words: give your UITableView a tableFooterView and set its frame's height to 0. This makes an actual separator show, with the right insets.
In more details: if you are using the storyboard, drag a UIView to the bottom of your Table View (in the tree view on the left) so it shows just below Table View Cell, at the same hierarchical level. This creates a tableFooterView. Of course this can be done programmatically as well.
Then, in your UITableViewController's implementation:
UIView *footerView = self.tableView.tableFooterView;
CGRect footerFrame = footerView.frame;
footerFrame.size.height = 0;
[footerView setFrame:footerFrame];
Let me know if that works for you! It might also work for the first separator if you use a tableHeaderView instead, I haven't tried it though.
So here's a super simple solution in Swift 4 which works:
Inside override func viewDidLoad(){}, I simply implemented this line of code:
self.tableView.tableFooterView = UIView(frame: .zero)
Hence it ensures that only the last cell gets the separator inset.
This worked perfectly for me, hope it does for you too!
this will do exactly what you want .. even though the line will take the entire width of the cell:
in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.tableView.separatorColor = [UIColor redColor];
self.tableView.separatorInset = UIEdgeInsetsZero;
You can do something like this if you are not using sections:
- (void)viewDidLoad
{
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(insetLeftSide, 0, width - insetRightSide, 1)];
}
If you are using sections implement the footer in each section as a one point View in the methods
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
}
This will allow you to have a separator for your last cell which in fact is not a separator is a footer that you can play with it and make it look like a separator
Swift 3
I found this old issue, so I tried the same in Swift:
tableView.tableFooterView = UIView()
tableView.tableFooterView?.height = 0 // Maybe not necessary
But it lead to another problem (in my case). So I solved it differently. I added an extra cell at the end of this section, empty and with height equal to zero:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return previousNumberOfRows + 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row == previousNumberOfRows ? 0 : previousCellHeight
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == items.count {
return UITableViewCell()
} else {
previousCellInitialization()
}
This is a less concise solution, but works in more cases, if you have multiple sections, existing footer view(s)...
I had a similar issue and found a workaround. Apple hides the last uitableviewcell separator and then displays it if you select the cell or if you call select and deselect on that cell.
So I taught the best is in - (void)layoutSubviews. The separator view is called _separatorView and it's a private property. Using the cell's selected / highlighted states you can come up with something like this:
- (void)layoutSubviews
{
// Call super so the OS can do it's layout first
[super layoutSubviews];
// Get the separator view
UIView *separatorView = [self valueForKey:#"_separatorView"];
// Make the custom inset
CGRect newFrame = CGRectMake(0.0, 0.0, self.bounds.size.width, separatorView.frame.size.height);
newFrame = CGRectInset(newFrame, 15.0, 0.0);
[separatorView setFrame:newFrame];
// Show or hide the bar based on cell state
if (!self.selected) {
separatorView.hidden = NO;
}
if (self.isHighlighted) {
separatorView.hidden = YES;
}
}
Something like this.
In iOS 8, if you have a plain style UITableView, and add a footer, the last separator is gone. However, you can easily recreate it by adding a custom separator view to the footer.
This example exactly mimics Today Widget separator style
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
//create footer view
let result = UIView()
result.frame.size.height = tableView.rowHeight
//recreate last cell separator, which gets hidden by footer
let sepFrame = CGRectMake(15, -0.5, tableView.frame.width, 0.5);
let vibrancyEffectView = UIVisualEffectView.init(effect: UIVibrancyEffect.notificationCenterVibrancyEffect())
vibrancyEffectView.frame = sepFrame
vibrancyEffectView.contentView.backgroundColor = tableView.separatorColor
result.addSubview(vibrancyEffectView)
return result
}
If you add an empty footer then the tableview will remove all the remaining line separators (for non-existent cells) but will still include the separator for the last cell:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
}
I used the table view style "grouped" to add this line:
And furthermore it avoids sticking the last separator line to stick on the screen when scrolling out!
Works in iOS 7.x and 8.x (put it in cellForRowAtIndexPath):
(PS substitute "max elements of your datasource" with your array datasource count)
if (row == <max elements of your datasource>-1) {
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height-1, self.view.frame.size.width, 1)];/// change size as you need.
separatorLineView.tag = 666;
separatorLineView.backgroundColor = [UIColor colorWithRed: 204.0/255.0 green: 204.0/255.0 blue: 204.0/255.0 alpha:1.0];
UIView *separator = [cell.contentView viewWithTag:666];
// case of orientation changed..
if (separator.frame.size.width != cell.contentView.frame.size.width) {
[[cell.contentView viewWithTag:666] removeFromSuperview];
separator = nil;
}
if (separator==nil) [cell.contentView addSubview:separatorLineView];
}
This is definitely help. Working.
but set separator "none" from attribute inspector.
Write following code in cellForRowAtIndexPath method
if(indexPath.row==arrData.count-1){
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,
cell.contentView.frame.size.height - 1.0,
cell.contentView.frame.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[cell.contentView addSubview:lineView];
}
The code below worked for me:
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 0.35)];
footerView.backgroundColor = [UIColor whiteColor];
CGRect frame = footerView.frame;
frame.origin.x = 15;
frame.size.width = frame.size.width - 15;
UIView *blackView = [[UIView alloc] initWithFrame:frame];
[blackView setBackgroundColor:[UIColor blackColor]];
blackView.alpha = 0.25;
[footerView addSubview:blackView];
tableView.tableFooterView = footerView;
Hope it works for you too.

cell.selectedBackgroundView covering up UIViews in a cell

I have a table. Within each cell of a table, I created a simple bar graph (which is just 2 UIViews with background filled).
I have set cell.selectedBackgroundView to an image.
When the cell is selected, it seems to cover up parts of the bar graph. Does anyone know why?
The red is the selected cell. The top and bottom are unselected cells:
In the image, the grey bar, the brown bar, the 2 numbers (x.xx) and the semi-transparent line at the left, are all subviews of 1 UIView. The UIView is added to the cell. The line and the 2 numbers are still there, but the 2 bars are gone.
Here's some code:
Cell selected image set like this:
UIImage *selectedRowImage = [UIImage imageNamed:#"table-selectedcellbg-red-45px-stretch.png"];
cell.selectedBackgroundView = [[UIImageView alloc]initWithImage:[selectedRowImage resizableImageWithCapInsets:UIEdgeInsetsMake(selectedRowImage.size.height, selectedRowImage.size.width/2, selectedRowImage.size.height, selectedRowImage.size.width/2)]];
[cell sendSubviewToBack:cell.selectedBackgroundView]; // This didn't make a difference
Adding the view set like this:
UIView *graph = [barGraph getGraph];
UIView *graphView = [[UIView alloc]initWithFrame:CGRectMake(150, (tableView.rowHeight - graph.frame.size.height)/2, graph.frame.size.width, graph.frame.size.height)];
[graphView addSubview:graph];
[cell addSubview:graphView];
Any ideas?
I think the answer can be found in the UITableViewClass Reference:
selectedBackgroundView
...
Discussion
The default is nil for cells in plain-style tables
(UITableViewStylePlain) and non-nil for section-group tables
(UITableViewStyleGrouped). UITableViewCell adds the value of this
property as a subview only when the cell is selected. It adds the
selected background view as a subview directly above the background
view (backgroundView) if it is not nil, or behind all other views.
Calling setSelected:animated: causes the selected background view to
animate in and out with an alpha fade.
It seems as if selectedBackgroundView only works well if the corresponding backgroundView property of the cell is not nil.
Try adding a backgroundView and test again.
Hope that helps you out.
Edit:
Since this wasn't the solution, I tried to reproduce your problem, but with no success: the backgroundView stayed behind the QuestionMarkIcon (a view like your graphView)..
Code:
- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath: (NSIndexPath*) indexPath {
//...
UIImage* selectedRowImage = [UIImage imageNamed: #"strecheableImage.png"];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage: [selectedRowImage resizableImageWithCapInsets: UIEdgeInsetsMake(selectedRowImage.size.height, selectedRowImage.size.width/2, selectedRowImage.size.height, selectedRowImage.size.width/2)]];
UIView* graph = [[QuestionMarkIcon alloc] init];
UIView* graphView = [[UIView alloc]initWithFrame: CGRectMake(150, (tableView.rowHeight - graph.frame.size.height)/2, graph.frame.size.width, graph.frame.size.height)];
[graphView addSubview: graph];
[cell addSubview: graphView];
// ...
}
This is how my stretchableImage.png looks like:
Cell 1 is selected but the QuestionMarkIcon (your graph) stays in front:
Sorry I couldn't help.

Eliminate extra separators below UITableView

When I set up a table view with 4 rows, there are still extra separators lines (or extra blank cells) below the filled rows.
How would I remove these cells?
Interface builder (iOS 9+)
Just drag a UIView to the table. In storyboard, it will sit at the top below your custom cells. You may prefer to name it "footer".
Here it is shown in green for clarity, you'd probably want clear color.
Note that by adjusting the height, you can affect how the "bottom bounce" of the table is handled, as you prefer. (Height zero is usually fine).
To do it programmatically:
Swift
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.tableFooterView = UIView()
}
Objective-C
iOS 6.1+
- (void)viewDidLoad
{
[super viewDidLoad];
// This will remove extra separators from tableview
self.tableView.tableFooterView = [UIView new];
}
or if you prefer,
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Historically in iOS:
Add to the table view controller...
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
// This will create a "invisible" footer
return CGFLOAT_MIN;
}
and if necessary...
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
// If you are not using ARC:
// return [[UIView new] autorelease];
}
Here's another way to do that w/out the grouped table style, and one you'd probably not guess. Adding a header and footer to the table (perhaps one or the other suffices, haven't checked) causes the separators to disappear from the filler/blank rows.
I stumbled onto this because I wanted a little space at the top and bottom of tables to decrease the risk of hitting buttons instead of a table cell with meaty fingers. Here's a method to stick a blank view in as header and footer. Use whatever height you like, you still eliminate the extra separator lines.
- (void) addHeaderAndFooter
{
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];
v.backgroundColor = [UIColor clearColor];
[self.myTableView setTableHeaderView:v];
[self.myTableView setTableFooterView:v];
[v release];
}
In response to #Casebash, I went back to the code in my app ("AcmeLists" List Manager in iTunes store...) and short-circuited the addHeaderAndFooter method to verify. Without it, I have the extra row separators; with the code, I have what you see in this window snap: no table row separators picture. So I'm not sure why it wouldn't have worked for you. Moreover, it makes sense to me that having any custom footer on a table view would necessarily have to stop drawing row separators for blank rows below it. That would be hideous. For reference, I looked at tables where there were more rows than could be viewed on screen, and then for a table with two rows. In both cases, no extraneous separators.
Perhaps your custom views were not actually added. To check that, set the background color to something other than clearColor, e.g., [UIColor redColor]. If you don't see some red bars at the bottom of the table, your footer wasn't set.
Removing extra separator lines for empty rows in UITableView in Swift
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.yourTableview.tableFooterView = UIView()
}
I would like to extend wkw answer:
Simply adding only footer with height 0 will do the trick. (tested on sdk 4.2, 4.4.1)
- (void) addFooter
{
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
[self.myTableView setTableFooterView:v];
}
or even simpler - where you set up your tableview, add this line:
//change height value if extra space is needed at the bottom.
[_tableView setTableFooterView:[[UIView alloc] initWithFrame:CGRectMake(0,0,0,0)]];
or even simplier - to simply remove any separators:
[_tableView setTableFooterView:[UIView new]];
Thanks to wkw again :)
For iOS 7+ using Storyboards
Simply drag a UIView into your UITableView as the footer. Set the footer view's height to 0.
Try this. It worked for me:
- (void) viewDidLoad
{
[super viewDidLoad];
// Without ARC
//self.tableView.tableFooterView = [[[UIView alloc] init] autorelease];
// With ARC, tried on Xcode 5
self.tableView.tableFooterView = [UIView new];
}
If you are using Swift, add the following code to viewDidLoad of the controller that manages the tableview:
override func viewDidLoad() {
super.viewDidLoad()
//...
// Remove extra separators
tableView.tableFooterView = UIView()
}
For Swift:
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
}
You can just add an empty footer at the end then it will hide the empty cells but it will also look quite ugly:
tableView.tableFooterView = UIView()
There is a better approach: add a 1 point line at the end of the table view as the footer and the empty cells will also not been shown anymore.
let footerView = UIView()
footerView.frame = CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 1)
footerView.backgroundColor = tableView.separatorColor
tableView.tableFooterView = footerView
just add this code (Swift) . .
tableView.tableFooterView = UIView()
Advancing J. Costa's solution: You can make a global change to the table by putting this line of code:
[[UITableView appearance] setTableFooterView:[[UIView alloc] initWithFrame:CGRectZero]];
inside the first possible method (usually in AppDelegate, in: application:didFinishLaunchingWithOptions: method).
Swift works great with:
tableView.tableFooterView = UIView()
I know this Question has be accepted answer but i put here different ways for how to hide Extra separator line of UITableView.
You can hide tableView's standard separator line, and add your custom line at the top of each cell.
Update:
The easiest way to add custom separator is to add simple UIView of 1px height:
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
separatorLineView.backgroundColor = [UIColor grayColor]; /// may be here is clearColor;
[cell.contentView addSubview:separatorLineView];
OR
self.tblView=[[UITableView alloc] initWithFrame:CGRectMake(0,0,320,370) style:UITableViewStylePlain];
self.tblView.delegate=self;
self.tblView.dataSource=self;
[self.view addSubview:self.tblView];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];
v.backgroundColor = [UIColor clearColor];
[self.tblView setTableHeaderView:v];
[self.tblView setTableFooterView:v];
[v release];
OR
- (float)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
// This will create a "invisible" footer
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
// To "clear" the footer view
return [[UIView new] autorelease];
}
OR
The best and simple way i like ever is
self.tableView.tableFooterView = [[UIView alloc] init];
Try any of one;
You may find lots of answers to this question. Most of them around manipulation with UITableView's tableFooterView attribute and this is proper way to hide empty rows. For the conveniency I've created simple extension which allows to turn on/off empty rows from Interface Builder.
You can check it out from this gist file. I hope it could save a little of your time.
extension UITableView {
#IBInspectable
var isEmptyRowsHidden: Bool {
get {
return tableFooterView != nil
}
set {
if newValue {
tableFooterView = UIView(frame: .zero)
} else {
tableFooterView = nil
}
}
}
}
Usage:
tableView.isEmptyRowsHidden = true
uitableview extra separator line hide extra separators lines hide in swift 3.0
self.tbltableView.tableFooterView = UIView(frame: .zero)
If you don't want any separator after the last cell, then you need a close to zero but non-zero height for your footer.
In your UITableViewDelegate:
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return .leastNormalMagnitude
}
Just add an view with the desired separator color as background color, 100% width, 1px height at the position x0 y-1 to your tableViewCell. Make sure the tableViewCell doesn't clip subviews, instead the tableView should.
So you get a absolut simple and working separator only between existing cells without any hack per code or IB.
Note: On a vertical top bounce the 1st separator shows up, but that shouldn't be a problem cause it's the default iOS behavior.
I was using a table view to show a fixed number of fixed height rows, so I simply resized it and made it non-scrollable.
To eliminate extra separator lines from bottom of UItableview programmatically, just write down following two lines of code and it will remove extra separator from it.
tableView.sectionFooterHeight = 0.f;
tableView.sectionHeaderHeight = 0.f;
This trick working for me all the time, try yourself.
I had some luck implementing a single piece of the accepted answer (iOS 9+, Swift 2.2). I had tried implementing:
self.tableView.tableFooterView = UIView(frame: .zero)
However, there was no effect on my tableView - I believe it may have something to do with the fact that I was using UITableViewController.
Instead, I only had to override the viewForFooterInSection method (I did not set the tableFooterView elsewhere):
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView(frame: .zero)
}
This worked fine for a tableView with a single section (if you have multiple sections, you need to specify the last one).
If you have only one section, then the quickest and easiest way is to just set the Table View Style from "Plain" to "Grouped". (see image)
If you have more sections, you might need to set the header height to zero (depending on your/your customer's/your project manager's taste)
If you have more sections, and don't want to mess with the headers (even if it is just one line in the simplest case), then you need to set a UIView as a footer, as it was explained in the previous answers)
Swift 4.0 Extension
Just a little extension for the storyboard:
extension UITableView {
#IBInspectable
var hideSeparatorForEmptyCells: Bool {
set {
tableFooterView = newValue ? UIView() : nil
}
get {
return tableFooterView == nil
}
}
}
Quick and easy Swift 4 way.
override func viewDidLoad() {
tableView.tableFooterView = UIView(frame: .zero)
}
If you are having static cells. You can also turn off the separator from Inspector window. (this won't be desirable if you need the separator. In that case use method shown above)
Try with this
for Objective C
- (void)viewDidLoad
{
[super viewDidLoad];
// This will remove extra separators from tableview
self.yourTableView.tableFooterView = [UIView new];
}
for Swift
override func viewDidLoad() {
super.viewDidLoad()
self.yourTableView.tableFooterView = UIView()
}
If you want to remove unwanted space in UITableview you can use below two methods
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.1;
}
I have added this small tableview extension that helps throughout
extension UITableView {
func removeExtraCells() {
tableFooterView = UIView(frame: .zero)
}
}
Swift 3 /Swift 4 /Swift 5 +, Very Easy and simple way
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//MARK:- For Hiding the extra lines in table view.
tableView?.tableFooterView = UIView()
}
OR
override func viewDidLoad(_ animated: Bool) {
super.viewDidLoad(animated)
//MARK:- For Hiding the extra lines in table view.
tableView?.tableFooterView = UIView()
}
Try this
self.tables.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 10.0f)];
UIKit does not create empty cell when the tableView has a tableFooterView. So we can make a trick and assign a zero height UIView object as footer of the tableView.
tableView.tableFooterView = UIView()
In case you have a searchbar in your view (to limit the number of results for example), you have to also add the following in shouldReloadTableForSearchString and shouldReloadTableForSearchScope:
controller.searchResultsTable.footerView = [ [ UIView alloc ] initWithFrame:CGRectZero ];

Resources