前言
一直有個誤解荐绝,認(rèn)為設(shè)置UITableViewCell的分割線距離cell左邊的間距比較麻煩低匙,總是隱藏自帶的分割線旷痕,添加一個1像素的View。不過在只需適配iOS8以后努咐,發(fā)現(xiàn)并不是很復(fù)雜苦蒿。就寫個測試的Demo,看看在不同版本系統(tǒng)的效果渗稍。
主要的測試代碼
TestTableViewController.m
@implementation TestTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"systemVersion = %@",[UIDevice currentDevice].systemVersion);
self.tableView.separatorInset = UIEdgeInsetsZero;
}
@end
ATableViewCell.m
@implementation ATableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.separatorInset = UIEdgeInsetsMake(0, 20, 0, 0);
}
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"ATableViewCell separatorInset = %@",NSStringFromUIEdgeInsets(self.separatorInset));
}
@end
BTableViewCell.m
@implementation BTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"BTableViewCell separatorInset = %@",NSStringFromUIEdgeInsets(self.separatorInset));
}
@end
不同版本下的效果
iOS 10
運行后的Log及效果
systemVersion = 10.3.1
ATableViewCell separatorInset = {0, 20, 0, 0}
BTableViewCell separatorInset = {0, 0, 0, 0}
很顯然佩迟,是預(yù)期的效果。
iOS 9
運行后的Log及效果
systemVersion = 9.0
ATableViewCell separatorInset = {0, 20, 0, 0}
BTableViewCell separatorInset = {0, 8, 0, 0}
從Log 和運行的效果圖都可以看出竿屹,ATableViewCell
的分割左邊有8個像素的間距报强,并沒有達到我們想設(shè)置為0的效果。
iOS 8
systemVersion = 8.1
ATableViewCell separatorInset = {0, 20, 0, 0}
BTableViewCell separatorInset = {0, 8, 0, 0}
和iOS9一樣拱燃,ATableViewCell
的分割左邊有8個像素的間距秉溉,并沒有達到我們想設(shè)置為0的效果。
問題所在
layoutMargins
在iOS8 UIView增加了layoutMargins屬性
@property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);
官方文檔解釋為
Use this property to specify the desired amount of space (measured in points) between the edge of the view and any subviews. Auto layout uses your margins as a cue for placing content. For example, if you specify a set of horizontal constraints using the format string “|-[subview]-|”, the left and right edges of the subview are inset from the edge of the superview by the corresponding layout margins. When the edge of your view is close to the edge of the superview and the preservesSuperviewLayoutMargins property is YES, the actual layout margins may be increased to prevent content from overlapping the superview’s margins.
The default margins are eight points on each side.
If the view is a view controller’s root view, the system sets and manages the margins. The top and bottom margins are set to zero points. The side margins vary depending on the current size class, but can be either 16 or 20 points. You cannot change these margins.
附上谷歌翻譯
使用此屬性指定視圖邊緣和任何子視圖之間所需的空間量(以點為單位)碗誉。 自動布局使用您的邊距作為放置內(nèi)容的提示召嘶。 例如,如果使用格式字符串“| - [subview] - |”指定一組水平約束哮缺,則子視圖的左邊緣和右邊緣將從超級視圖的邊緣插入相應(yīng)的布局邊距弄跌。 當(dāng)您的視圖的邊緣靠近超級視圖的邊緣并且preservesuperviewLayoutMargins屬性為YES時,可能會增加實際的布局邊距尝苇,以防止內(nèi)容與超級視圖的邊距重疊铛只。
默認(rèn)邊距是每邊八點。
如果視圖是視圖控制器的根視圖糠溜,系統(tǒng)將設(shè)置和管理邊距淳玩。 頂部和底部邊距設(shè)置為零點。 側(cè)邊距根據(jù)當(dāng)前大小類別而變化非竿,但可以是16或20點蜕着。 您不能更改這些邊距。
大致的意思就是在布局子控件時红柱,子控件的frame會依據(jù)此屬性增加相應(yīng)的間距承匣。在Storyboard
或xib
中,對應(yīng)的就是在添加約束時豹芯,一般都會取消勾選的屬性
所以悄雅,在BTableViewCell
中添加如下代碼就可以實現(xiàn)在iOS 8和iOS 9分割線左邊的間距為0
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.layoutMargins = UIEdgeInsetsZero;
}
添加后的Log及效果
systemVersion = 9.0
ATableViewCell separatorInset = {0, 20, 0, 0}
BTableViewCell separatorInset = {0, 0, 0, 0}
preservesSuperviewLayoutMargins
同樣是iOS 8增加的屬性
// default is NO - set to enable pass-through or cascading behavior of margins from this view’s parent to its children
@property (nonatomic) BOOL preservesSuperviewLayoutMargins NS_AVAILABLE_IOS(8_0);
官方文檔的解釋為
When the value of this property is YES, the superview’s margins are also considered when laying out content. This margin affects layouts where the distance between the edge of a view and its superview is smaller than the corresponding margin. For example, you might have a content view whose frame precisely matches the bounds of its superview. When any of the superview’s margins is inside the area represented by the content view and its own margins, UIKit adjusts the content view’s layout to respect the superview’s margins. The amount of the adjustment is the smallest amount needed to ensure that content is also inside the superview’s margins.
The default value of this property is NO.
大致理解為,若設(shè)置該屬性為YES
铁蹈,相當(dāng)與寫了這句代碼self.layoutMargins = super.layoutMargins
所以在修改BTableViewCell
的代碼為如下后
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.preservesSuperviewLayoutMargins = YES;
self.layoutMargins = UIEdgeInsetsZero;
}
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"BTableViewCell layoutMargins = %@",NSStringFromUIEdgeInsets(self.layoutMargins));
NSLog(@"BTableViewCell separatorInset = %@",NSStringFromUIEdgeInsets(self.separatorInset));
}
得到的Log和效果
systemVersion = 8.1
ATableViewCell separatorInset = {0, 20, 0, 0}
BTableViewCell layoutMargins = {0, 16, 0, 16}
BTableViewCell separatorInset = {0, 16, 0, 0}
和預(yù)期的一樣宽闲,BTableViewCell
的layoutMargins
并不為0众眨,而是父視圖的{0, 16, 0, 16}
在layoutMargins
的文檔中也提到
If the view is a view controller’s root view, the system sets and manages the margins. The top and bottom margins are set to zero points. The side margins vary depending on the current size class, but can be either 16 or 20 points. You cannot change these margins.
BTalbeViewCell
的父控件時tableView
,tableView
是TestTableViewController
的root view
容诬,所以tableView
的左右layoutMargin
都為16
總結(jié)
- 設(shè)置
self.tableView.separatorInset = UIEdgeInsetsZero;
可調(diào)整tableView
中所有的cell
的separatorInset
- 若
cell
設(shè)置了separatorInset
則會依據(jù)cell
的separatorInset
來調(diào)整 - 在iOS 9 和iOS 8 中需要設(shè)置
self.layoutMargins = UIEdgeInsetsZero
娩梨,才能達到邊距為0的效果
以上是本人測試后所得出的結(jié)論,并且是第一次寫博客览徒,不對之處還請多多包涵狈定、指正。