I have a UITableView
where the separators don't have the full width. It ends like 10 pixels before the left side. I was playing around with this code in the viewDidLoad()
.
self.tableView.layoutMargins = UIEdgeInsetsZero;
Also in the storyboard when you can select custom or default selectors. Now all the cells that are populated don't have the full-width selectors but the cells that are empty have full width.
How can I fix this?
UITableView
has a property separatorInset
. Set the inset of the UITableView
line separator to zero. Also you can change the separatorInset
from the storyboard
This worked for me on iOS 8.4 - 9.0 devices using Xcode 6.4 and Swift 1.2:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
Swift 5 Update:
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
In your UITableViewCell
Go to Attributes Inspector in your Interface Builder and simply change "15" to 0. Do this for all the cells you wish to change.
https://i.stack.imgur.com/A8rY1.png
You may need to add [cell setLayoutMargins:UIEdgeInsetsZero];
to your tableViewCell
I got the answer from this post: iOS 8 UITableView separator inset 0 not working
Just add this code on your UITableViewController
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
viewDidLayoutSubviews
is not necessary
for Swift 3 :
override func viewDidLoad() {
super.viewDidLoad()
tableView.separatorInset = .zero
tableView.layoutMargins = .zero
}
Select your UITableViewCell Go to Atributes Inspector Go to Separator and change it to "custom Insets" Set left and / or right fields. (By default left: 15, right: 0)
Look how it works (using left: 100
):
https://i.stack.imgur.com/zlC8T.png
Result:
https://i.stack.imgur.com/Uuv0N.png
I inherit from UITableViewController
and needed additional to the two insets settings in willDisplayCell
also to set preservesSuperviewLayoutMargins
to false. In Swift it looks like this:
override func tableView(_tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
cell.preservesSuperviewLayoutMargins = false
}
}
preservesSuperviewLayoutMargins = false
because default value is already false
The Separator Inset
is by default 15 from left. Change Separator Inset
option from auto
to custom
and set the inset to 0
.
https://i.stack.imgur.com/l40TC.png
For Swift in iOS 9+
If using a custom UITableViewCell
:
override var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set(newVal) {}
}
then for your UITableView
in viewDidLoad
:
self.tableView?.separatorInset = UIEdgeInsetsZero;
self.tableView?.layoutMargins = UIEdgeInsetsZero;
For people having issues with the iPad — this will get you in a state that is the same as the iPhone. You can then adjust the separatorInset
as needed.
tableView.cellLayoutMarginsFollowReadableWidth = false
Use it in cellForRowAtIndexPath
method, to configure cell's separator specs ,
it works perfect for iOS9.0+
cell.separatorInset = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
Tested for iOS 9.3 & Swift 2.2. Make sure to put the code in willDisplayCell
which is called just before displaying the cell and not in cellForRowAtIndexPath
where you create the cell only.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
}
Add override
to the function for UITableViewController
, like so:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
swift 5, Xcode 11 Update
place this inside viewDidLoad()
yourTableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
for edge to edge separator just set the value of left and right to 0.
by the way change the "yourTableView" to your tableView Outlet name.
UIEdgeInsets.zero
None of the above worked for me in Swift 2.2 and Xcode 7.3.1
Turned out to be the simplest solution of all. No code needed. Just change TableViewCell
Layout Margins values in your UITableView
inspector:
https://i.stack.imgur.com/0TC8z.png
For Swift 3 :
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = UIEdgeInsets.zero
}
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = UIEdgeInsets.zero
}
if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
}
In viewDidLoad
(tested iOS11 - swift 4.1)
try
tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
None of these solutions work on the iPad, but I have come up with a solution that covers both devices:
With reusable cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
...[other code]...
[cell setLayoutMargins:UIEdgeInsetsZero];
[cell setSeparatorInset:UIEdgeInsetsZero];
return cell;
}
With non reusable cells:
- (void)removeSeparatorInset:(UITableView*)tableView{
NSArray *cells = [tableView visibleCells];
for (UITableViewCell *cell in cells){
[cell setLayoutMargins:UIEdgeInsetsZero];
[cell setSeparatorInset:UIEdgeInsetsZero];
}
}
-(void) viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self removeSeparatorInset:self.tableView];
}
Just to expand on this approach:
@property(nonatomic) UIEdgeInsets separatorInset;
@property(nonatomic) UIEdgeInsets layoutMargins;
Both properties can be used by UITableView
& UITableViewCell
. The latter is, in fact, a property of UIView
, which is a parent class of both UITableView
& UITableViewCell
.
Success story sharing