By default UITableView manages cell separator views by itself. You only can set separatorColor and separatorStyle properties for the table, which actually is quite limiting because style could be 'no separators', solid line or etched line. If you want to use dotted line or specify some offsets then you are out of luck.
What's interesting is that cells actually have references to separator views. Just open UITableViewCell.h file and look at cell's ivars; it has
UIView *_separatorView;
UIView *_topSeparatorView;
which are clearly bottom and top separator views for the cell. I don't know why Apple does not expose them or does not allow to customize them in some way—it could have saved so much timeā¦
So what could be done to alleviate this? How could we provide our own custom separators? The easiest solution (and I guess that's what most devs do) is to set separatorStyle to 'no separators' and add custom separator views to the content view of every cell. It works, but not that well. First you have to hide top separator view for each cell except the one at the bottom and what's most important these views are resized when table is being edited.
Another solution which I provide here is to add separators as cells. I've written a special table provider that wraps your provider (data source + delegate) and inserts these cells. Below is an API of this provider:
enum {
BACellSeparatorPositionNone = 0,
BACellSeparatorPositionTop = 1 << 0,
BACellSeparatorPositionBottom = 1 << 1
};
typedef NSUInteger BACellSeparatorPositions;
@protocol BASeparatedTableProviderDelegate
<NSObject, UITableViewDataSource, UITableViewDelegate>
- (BACellSeparatorPositions)tableView:(UITableView *)tableView
separatorPositionsForRow:(NSIndexPath *)indexPath;
- (UITableViewCell *)tableView:(UITableView *)tableView
topSeparatorCellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (UITableViewCell *)tableView:(UITableView *)tableView
bottomSeparatorCellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView
heightForTopSeparatorRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView
heightForBottomSeparatorRowAtIndexPath:(NSIndexPath *)indexPath;
@end
@interface BASeparatedTableProvider : NSObject
<UITableViewDataSource, UITableViewDelegate>
@property(nonatomic, assign) id<BASeparatedTableProviderDelegate> delegate;
- (NSIndexPath *)separatedIndexPathForIndexPath:(NSIndexPath *)indexPath;
- (NSArray *)separatedIndexPathsForIndexPaths:(NSArray *)indexPaths;
@end
So all that you have to do is to implement five methods that provide separator positions for the cell, their views and heights. In most cases top and bottom separators are the same so effectively you have to add code just to create the custom separator cell.
Class BASeparatedTableProvider is part of the BaseAppKit framework but does not depend much on other classes so you can just copy it into your project. Not all methods are implemented yet; you should be able to show table contents and edit it but some delegate methods just won't be called.
I was not sure about performance of this approach and its feasibility but so far it works well. I'm using this code in production and there seems to be no issues with it.


