How to customize tableView separator in iPhone

IphoneUitableview

Iphone Problem Overview


By default there is a single line separator in uitableview.

But I want to put my customized line as a separator.

Is it possible? How?

Iphone Solutions


Solution 1 - Iphone

If you want to do more than change the color of the separator using the separatorColor property of the UITableView then you could set the separatorStyle property to UITableViewCellSeparatorStyleNone and then either:

  • create custom UITableViewCells that include your custom seperator within them
  • create alternate [UITableViewCell][6]s that include your custom separator

For example, if your table currently displays 5 rows you could update it to display 9 rows and the rows at index 1, 3, 5, 7 would be separator cells.

Solution 2 - Iphone

A better solution is to use the cell's current width and height. Something like this:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height - 1.0, cell.contentView.frame.size.width, 1)];

lineView.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview:lineView];

Solution 3 - Iphone

If you need different seperator colors for different rows OR you want the seperator to remain visible when the row is highlighted on tap then try this:

self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    
// We have to use the borderColor/Width as opposed to just setting the 
// backgroundColor else the view becomes transparent and disappears during 
// the cell's selected/highlighted animation
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake(0, 43, 1024, 1)];
separatorView.layer.borderColor = [UIColor redColor].CGColor;
separatorView.layer.borderWidth = 1.0;
[cell.contentView addSubview:separatorView];

This assumes your cell's background color is transparent.


The above solution came out of some extensive experimentation. Here's some notes on my findings that I'm sure will help people:

In the normal “not selected” state

  • The contentView (whats in your XIB unless you coded it otherwise) is drawn normally
  • The selectedBackgroundView is HIDDEN
  • The backgroundView is visible (so provided your contentView is transparent you see the backgroundView or (if you have not defined a backgroundView you'll see the background colour of the UITableView itself)

A cell is selected, the following occurs immediately with-OUT any animation:

  • All views/subviews within the contentView have their backgroundColor cleared (or set to transparent), label etc text color's change to their selected colour
  • The selectedBackgroundView becomes visible (this view is always the full size of the cell (a custom frame is ignored, use a subview if you need to). Also note the backgroundColor of subViews are not displayed for some reason, perhaps they're set transparent like the contentView). If you didn't define a selectedBackgroundView then Cocoa will create/insert the blue (or gray) gradient background and display this for you)
  • The backgroundView is unchanged

When the cell is deselected, an animation to remove the highlighting starts:

  • The selectedBackgroundView alpha property is animated from 1.0 (fully opaque) to 0.0 (fully transparent).
  • The backgroundView is again unchanged (so the animation looks like a crossfade between selectedBackgroundView and backgroundView)
  • Only once the animation has finished does the contentView get redrawn in the "not-selected" state and its subview backgroundColor's become visible again (this can cause your animation to look horrible so it is advisable that you don't use UIView.backgroundColor in your contentView)

Solution 4 - Iphone

These answers result in the highlight rect being overwritten by the separator you add to your cell (on iOS 6 with my testing at least). You need to set the separatorColor to [UIColor clearColor] so that cells are still separated by 1px, you can then draw your separator in the gap:

- (void)viewDidLoad {
    self.tableView.separatorColor = [UIColor clearColor];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // snip
    CALayer *separator = [CALayer layer];
    separator.backgroundColor = [UIColor redColor].CGColor;
    separator.frame = CGRectMake(0, 43, self.view.frame.size.width, 1);
    [cell.layer addSublayer:separator];
    return cell;
}

Solution 5 - Iphone

You add the following code cellForRowAtIndexPath delegate of tableView to create a custom image view of 1px height and 200px width for everyCell

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[cell.contentView addSubview:lineView];

Note: i dont know how heavy it is on the performance.

Solution 6 - Iphone

I dont know if this can be done "automatically" with some setting. But a suggestion would be to set the line separator as none, and in the borders of your cells actually draw your line separator that you want..

Solution 7 - Iphone

If you are using Custom Cells in Swift: An alternative approach is to extend UITableViewCell with a function that can draw a line at the top of that cell.

import UIKit

extension UITableViewCell {
    func addSeparatorLineToTop(){
        let lineFrame = CGRectMake(0, 0, bounds.size.width, 1)
        let line = UIView(frame: lineFrame)
        line.backgroundColor = UIColor.myGray_300()
        addSubview(line)
    }
}

Then you can add this line to any custom cell, for example in the awakeFromNib

override func awakeFromNib() {
    super.awakeFromNib()
    addSeparatorLineToTop()
}

This solution is nice because it does not mess up your storyboard and limits your extra code to 1 line.

Solution 8 - Iphone

On a retina display, even drawing a 0.5 unit line will result in a two-pixel line, due to anti-aliasing. To render it as a single pixel on both displays, shift it up one quarter of a unit:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, self.contentView.frame.size.height - (1.0 - 0.25), self.contentView.frame.size.wi
lineView.backgroundColor = [UIColor colorWithRed:(230.0/255.0f) green:(233/255.0f) blue:(237.0/255.0f) alpha:1.0f];
[self.contentView addSubview:lineView];

Solution 9 - Iphone

Tested on iOS 7 (GM):

@implementation MyTableViewController

- (void)viewDidLayoutSubviews {
    for (UIView *view in self.view.subviews) {
        if ([view isKindOfClass:NSClassFromString(@"_UITableViewCellSeparatorView")])
            view.backgroundColor = [UIColor redColor];
    }
}

@end

NOTE: it appears the UITableView moves separators to the cells in some configurations, which would make this code not work unless you descend into all UITableViewCells as well.

Solution 10 - Iphone

Swift version:

private let kSeparatorTag = 123
private let kSeparatorHeight: CGFloat = 1.5

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.viewWithTag(kSeparatorTag) == nil //add separator only once
    {
        let separatorView = UIView(frame: CGRectMake(0, cell.frame.height - kSeparatorHeight, cell.frame.width, kSeparatorHeight))
        separatorView.tag = kSeparatorId
        separatorView.backgroundColor = UIColor.redColor()
        separatorView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        
        cell.addSubview(separatorView)
    }
}

Solution 11 - Iphone

The cell in gist below is a UITableViewCell's subclass where each cell could have its own separator w/ many styles (currently only .None and .Default are supported). It is written in Swift and assumes Autolayout usage.

https://gist.github.com/evgeniyd/fa36b6f586a5850bca3f

How to use the class:

  1. set UITableView object's separator style to UITableViewCellSeparatorStyle.None

     tableView.separatorStyle = .None
    
  2. Create a subclass of MPSTableViewCell

  3. Somewhere inside awakeFromNib() set cell's separator style

Note: the code below assumes cell is loaded from xib/storyboard

    class FASWorkoutCell: FASTableViewCell {
    
    required init(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
     }

     override func awakeFromNib() {
         super.awakeFromNib()
    
         separatorType = .Default
     }
     
     // ...

     }

Solution 12 - Iphone

If you use a customized UITableViewCell, You can simply add UIView on the bottom of the UItableViewCell.xib and put the background colour as the colour you want.

For example, on xib I add a UIView on the bottom and set the height as 1. Using autolayout, I set left constraint to 12, bottom constraint to 0, right constraint to 0 and height to 1.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSagar KothariView Question on Stackoverflow
Solution 1 - IphoneDaniel RichardsonView Answer on Stackoverflow
Solution 2 - IphoneJerry DestrempsView Answer on Stackoverflow
Solution 3 - IphoneOliver PearmainView Answer on Stackoverflow
Solution 4 - IphonemxclView Answer on Stackoverflow
Solution 5 - IphonecarbonrView Answer on Stackoverflow
Solution 6 - IphoneDanielView Answer on Stackoverflow
Solution 7 - IphonePbkView Answer on Stackoverflow
Solution 8 - IphonetooluserView Answer on Stackoverflow
Solution 9 - IphonemxclView Answer on Stackoverflow
Solution 10 - IphoneChikabuZView Answer on Stackoverflow
Solution 11 - IphoneYevhen DubininView Answer on Stackoverflow
Solution 12 - IphoneKyle JuView Answer on Stackoverflow