use*_*727 656 objective-c uitableview ios swift ios8
我有一个应用程序,其中UITableView的分隔符插入设置为自定义值 - 右0,左0.这完美地工作iOS 7.x,但在iOS 8.0我看到分隔符插入设置为15右侧的默认值.即使在它设置的xib文件中0,它仍然显示不正确.
如何删除UITableViewCell分隔符边距?
cds*_*per 1068
iOS 8.0在单元格和表视图上引入了layoutMargins属性.
此属性在iOS 7.0上不可用,因此您需要确保在分配之前进行检查!
此外,Apple已向您的单元格添加了一个属性,以防止它继承您的表格视图的边距设置.设置此属性后,您的单元格可以独立于表视图配置自己的边距.把它想象成一个覆盖.
调用此属性layoutMargins,并将其设置为preservesSuperviewLayoutMargins允许单元格的NO设置覆盖layoutMarginTableView上设置的任何内容.它既节省了时间(您不必修改表视图的设置),而且更简洁.有关详细说明,请参阅Mike Abdullah的答案.
注意:以下是针对单元级边距设置的简洁实现,如Mike Abdullah的回答所述.设置单元格layoutMargin将确保表视图不会覆盖单元格设置.如果您确实希望整个表格视图具有一致的边距,请相应地调整您的代码.
设置细胞边距:
-(UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero // override any margins inc. safe area
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特4:
override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }
Run Code Online (Sandbox Code Playgroud)
将preservesSuperviewLayoutMargins=NO单元格上的属性设置为NO 应该可以防止表格视图覆盖单元格边距.在某些情况下,它似乎无法正常运作.
如果全部失败,您可以强制执行表格视图边距:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove seperator inset
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
// Prevent the cell from inheriting the Table View's margin settings
if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
// Explictly set your cell's layout margins
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特4:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// Remove seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
Run Code Online (Sandbox Code Playgroud)
......你去!这应该适用于iOS 7和8.
编辑: 穆罕默德·萨利赫带给我的注意的iOS 9可能发生变化,您可能需要设置表视图的preservesSuperviewLayoutMargins到cellLayoutMarginsFollowReadableWidth,如果你想定制插图或利润.您的里程可能会有所不同,但未记录在案.
此属性仅存在于iOS 9中,因此请务必在设置之前进行检查.
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Force your tableview margins (this may be a bad idea)
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特4:
func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
tableView.separatorInset = .zero
}
if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
tableView.layoutMargins = .zero
}
}
Run Code Online (Sandbox Code Playgroud)
(以上代码来自iOS 8 UITableView分隔符插入0不起作用)
编辑:这是一个纯粹的Interface Builder方法:
注意:iOS 11更改并简化了大部分此类行为,即将发布更新...
use*_*727 257
精氨酸!在您的Cell子类中执行此操作之后:
- (UIEdgeInsets)layoutMargins
{
return UIEdgeInsetsZero;
}
Run Code Online (Sandbox Code Playgroud)
或者cell.layoutMargins = UIEdgeInsetsZero;为我设置修复它.
Mik*_*lah 178
让我们花点时间了解问题,然后盲目收费以尝试解决问题.
在调试器中快速浏览将告诉您分隔线是子视图UITableViewCell.看起来细胞本身对这些细胞系的布局负有相当大的责任.
iOS 8引入了布局边距的概念.默认情况下,视图的布局边距8pt位于所有方面,并且它们是从祖先视图继承的.
我们可以告诉您,在布置其分隔线时,UITableViewCell选择尊重左侧布局边距,使用它来约束左侧插图.
将所有这些组合在一起,以实现真正零的理想插入,我们需要:
0就这样,这是一个非常简单的任务:
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
Run Code Online (Sandbox Code Playgroud)
注意事项:
preservesSuperviewLayoutMargins.preservesSuperviewLayoutMargins您可以将祖先视图(例如表格)配置为0保留左边距,而不是设置,但这似乎更容易出错,因为您无法控制整个层次结构.0并留下其他边距可能会稍微清晰一些.UITableView在普通样式表底部绘制的"额外"分隔符上有一个0插图,我猜这将需要在表级别指定相同的设置(没试过这个!)Ric*_*cky 58
我相信这是我在这里提出的问题:删除iOS 8上的SeparatorInset UITableView for XCode 6 iPhone模拟器
在iOS 8中,所有对象都有一个新属性UIView.因此,SeparatorInset在iOS 7.x中设置的解决方案将无法删除您在iOS 8中的UITableView上看到的空白区域.
新属性称为" 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
Run Code Online (Sandbox Code Playgroud)

解决方案:-
-(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];
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在cell.layoutMargins = UIEdgeInsetsZero;未检查是否layoutMargins存在的情况下进行设置,则应用程序将在iOS 7.x上崩溃.因此,最好的方法是先检查是否layoutMargins存在setLayoutMargins:UIEdgeInsetsZero.
Luk*_*asz 46
您可以在应用程序启动时(在加载UI之前)使用UIAppearance一次,将其设置为默认全局设置:
// 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];
}
Run Code Online (Sandbox Code Playgroud)
这样,您可以保持UIViewController的代码干净,并且可以随时覆盖它.
Kin*_*ard 41
iOS在单元格和表视图上引入了layoutMargins属性.
此属性在iOS 7.0中不可用,因此您需要确保在分配之前进行检查!
但是,Apple已将一个名为preservesSuperviewLayoutMargins的属性添加到您的单元格中,这将阻止它继承您的表格视图的边距设置.这样,您的单元格可以独立于表视图配置自己的边距.把它想象成一个覆盖.
此属性称为preservesSuperviewLayoutMargins,将其设置为NO可以允许您使用自己的单元格的layoutMargin设置覆盖Table View的layoutMargin设置.它既节省了时间(您不必修改表视图的设置),而且更简洁.有关详细说明,请参阅Mike Abdullah的答案.
注意:正如Mike Abdullah的回答所表达的那样,这是正确的,不那么混乱的实现; 设置单元格的preservesSuperviewLayoutMargins = NO将确保您的表视图不会覆盖单元格设置.
第一步 - 设置细胞边距:
/*
Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath)
{
// Remove separator inset
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
}
Run Code Online (Sandbox Code Playgroud)
将单元格上的preservesSuperviewLayoutMargins属性设置为NO 应该可以防止表视图覆盖单元格边距.在某些情况下,它似乎无法正常运作.
第二步 - 只有在所有操作都失败的情况下,您才可以强制执行Table View边距:
/*
Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
}
Run Code Online (Sandbox Code Playgroud)
......你去!这应该适用于iOS 8和iOS 7.
注意:使用iOS 8.1和7.1测试,在我的情况下我只需要使用此解释的第一步.
只有在渲染单元格下面有未填充的单元格时才需要第二步,即.如果表大于表模型中的行数.不执行第二步将导致不同的分隔符偏移.
swi*_*ams 38
在Swift中,它稍微更烦人,因为它layoutMargins是一个属性,所以你必须覆盖getter 和 setter.
override var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set(newVal) {}
}
Run Code Online (Sandbox Code Playgroud)
这将有效地使layoutMarginsreadonly,在我的情况下是好的.
Jul*_*ról 22
对于iOS 9,您需要添加:
if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅问题.
Dan*_*ieu 20
Swift 2.0扩展
我只是想分享一个扩展,我从tableview单元格分隔符中删除边距.
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
用于上下文:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.removeMargins()
return cell
Run Code Online (Sandbox Code Playgroud)
Ale*_*kov 15
迅速:
override func viewDidLoad() {
super.viewDidLoad()
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
self.tableView.layoutIfNeeded() // <--- this do the magic
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
return cell
}
Run Code Online (Sandbox Code Playgroud)
ide*_*awu 11
我这样做是通过这样做的:
tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;
Run Code Online (Sandbox Code Playgroud)
小智 9
至于cdstamper建议的是什么而不是表视图,在单元格的layoutSubview方法中添加以下行对我有用.
- (void)layoutSubviews
{
[super layoutSubviews];
if ([self respondsToSelector:@selector(setSeparatorInset:)])
[self setSeparatorInset:UIEdgeInsetsZero];
if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
{
[self setPreservesSuperviewLayoutMargins:NO];;
}
if ([self respondsToSelector:@selector(setLayoutMargins:)])
{
[self setLayoutMargins:UIEdgeInsetsZero];
}
}
Run Code Online (Sandbox Code Playgroud)
这是完全控制这些东西的唯一方法(我能找到)
要完全控制每个单元格上的分隔符插入和布局边距.willDisplayCell在您的方法中执行此操作UITableviewDelegate.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.layoutMargins = UIEdgeInsetsZero
cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}
Run Code Online (Sandbox Code Playgroud)
单元格对象控制分隔符,contentView控制其他所有内容.如果您的分隔符插入空间以意外颜色显示,则应解决此问题:
cell.backgroundColor = cell.contentView.backgroundColor
Run Code Online (Sandbox Code Playgroud)
Swift 3.0示例:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// removing seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// prevent the cell from inheriting the tableView's margin settings
if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// explicitly setting cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
Run Code Online (Sandbox Code Playgroud)
Swift for iOS 8中的简单解决方案,带有自定义功能UITableViewCell
override func awakeFromNib() {
super.awakeFromNib()
self.layoutMargins = UIEdgeInsetsZero
self.separatorInset = UIEdgeInsetsZero
}
Run Code Online (Sandbox Code Playgroud)
这样你设置layoutMargin和separatorInset只是一个时间,而不是做它的每一个willDisplayCell作为最上面的答案的建议.
如果您使用自定义,UITableViewCell这是正确的位置.否则你应该这样做tableView:cellForRowAtIndexPath.
只是另一个提示:你不需要设置preservesSuperviewLayoutMargins = false因为默认值已经存在NO!
只需添加以下代码即可解决此程序.
祝你好运!
-(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];
}
}
Run Code Online (Sandbox Code Playgroud)
viewDidLayoutSubviews大多数答案都显示通过单元格和表格视图的各种方法(即,,等)设置分隔符willDisplayCell插入和布局边距,但我发现仅将这些放入cellForRowAtIndexPath效果很好。似乎是最干净的方式。
// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
cell.preservesSuperviewLayoutMargins = NO;
[cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
[cell setSeparatorInset:UIEdgeInsetsZero];
Run Code Online (Sandbox Code Playgroud)
使用下面的代码片段可以避免 iOS 8 和 7 中 UITableView 出现不必要的填充问题。
-(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];
}
}
Run Code Online (Sandbox Code Playgroud)
这是在Swift中为我工作的代码:
override func viewDidLoad()
{
super.viewDidLoad()
...
if tableView.respondsToSelector("setSeparatorInset:") {
tableView.separatorInset = UIEdgeInsetsZero
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector("setLayoutMargins:") {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins.left = CGFloat(0.0)
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎是最干净的(现在),因为所有cell/tableView边缘/边距调整都是在tableView:willDisplayCell:forRowAtIndexPath:方法中完成的,而不会将不必要的代码填入tableView:cellForRowAtIndexPath:.
顺便说一句,我只是设置单元格的左侧separatorInset/layoutMargins,因为在这种情况下我不想搞砸我在单元格中设置的约束.
代码更新为Swift 2.2:
override func viewDidLoad() {
super.viewDidLoad()
if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
tableView.separatorInset = UIEdgeInsetsZero
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
if cell.respondsToSelector(Selector("setSeparatorInset:")) {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector(Selector("setLayoutMargins:")) {
cell.layoutMargins.left = CGFloat(0.0)
}
}
Run Code Online (Sandbox Code Playgroud)
我建议不要更新preservesSuperviewLayoutMargins并且layoutMargins每次单元格滚动(使用willDisplayCell)时,我建议在以下位置执行一次cellForRowAtIndexPath::
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
Run Code Online (Sandbox Code Playgroud)
Lukasz在Swift中回答:
// iOS 7:
UITableView.appearance().separatorStyle = .SingleLine
UITableView.appearance().separatorInset = UIEdgeInsetsZero
UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero
// iOS 8:
if UITableView.instancesRespondToSelector("setLayoutMargins:") {
UITableView.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
}
Run Code Online (Sandbox Code Playgroud)
在iOS8中:
将其添加到我的 UITableViewCell 子类中:
- (UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero;
}
Run Code Online (Sandbox Code Playgroud)
并将其设置为“tableView:cellForRowAtIndexPath”或“tableView:willDisplayCell”:
[editCell setSeparatorInset:UIEdgeInsetsZero];
Run Code Online (Sandbox Code Playgroud)
为我工作。
| 归档时间: |
|
| 查看次数: |
180798 次 |
| 最近记录: |