I have an app where the UITableView
\'s separator inset is set to custom values - Right 0
, Left 0
. This works perfectly in iOS 7.
I believe this is the same question that I asked here: Remove SeparatorInset on iOS 8 UITableView for XCode 6 iPhone Simulator
In iOS 8, there is one new property for all the objects inherit from UIView
. So, the solution to set the SeparatorInset
in iOS 7.x will not be able to remove the white space you see on the UITableView in iOS 8.
The new property is called "layoutMargins".
@property(nonatomic) UIEdgeInsets layoutMargins
Description The default spacing to use when laying out content in the view.
Availability iOS (8.0 and later)
Declared In UIView.h
Reference UIView Class Reference
The solution:-
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
If you set cell.layoutMargins = UIEdgeInsetsZero;
without checking if the layoutMargins
exists, the app will crash on iOS 7.x. So, the best way would be checking if the layoutMargins
exists first before setLayoutMargins:UIEdgeInsetsZero
.
You can use UIAppearance once, at your application startup (before UI is loaded), to set it as default global settings:
// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];
// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
[[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}
This way, you keep your UIViewController's code clean and can always override it if you want.
Swift 2.0 Extension
I just wanted to share an extension I made to remove the margins from the tableview cell separators.
extension UITableViewCell {
func removeMargins() {
if self.respondsToSelector("setSeparatorInset:") {
self.separatorInset = UIEdgeInsetsZero
}
if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
self.preservesSuperviewLayoutMargins = false
}
if self.respondsToSelector("setLayoutMargins:") {
self.layoutMargins = UIEdgeInsetsZero
}
}
}
Used in context:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.removeMargins()
return cell
Here's an easy way to globally remove the inset.
In UITableViewCell+Extensions.swift
:
import UIKit
extension UITableViewCell {
override public var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set { }
}
}
In AppDelegate
application:didFinishLaunchingWithOptions:
:
UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero
You might think to a) also just override separatorInset
in the extension, or b) set the appearance proxy for layoutMargins
, instead. Neither will work. Even though separatorInset
is indicated to be a property, attempting to override it as a property (or method) generates compiler errors. And setting the appearance proxy for UITableViewCell
's layoutMargins
(or, for that matter, also setting the appearance proxies for UITableView
's layoutMargins
and separatorInset
) has no effect.
This is my solution. This applies to the custom cell subclass, just add them both to the subclass.
- (UIEdgeInsets)layoutMargins {
return UIEdgeInsetsMake(0, 10, 0, 10);
}
2.
self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);
And it is convenient that you can customize the position of the separator without asking your designer to draw one for you..........
Adding this snippet, simple elegant in Swift works for me in iOS8 :)
// tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
}