iOS 9 UITableView 分隔符插入(显着的左边距)

Posted

技术标签:

【中文标题】iOS 9 UITableView 分隔符插入(显着的左边距)【英文标题】:iOS 9 UITableView separators insets (significant left margin) 【发布时间】:2015-10-10 19:08:27 【问题描述】:

我在ios 9 上的UITableView 中的UITableViewCells 之间存在分隔符问题。他们有很大的左边距。我已经有了删除iOS 8 引入的间距的代码,但它不适用于iOS 9。看起来他们添加了其他东西。我想它可能与layoutMarginsGuide 有关,但我还没有弄清楚。有没有人遇到过类似的问题并找到了解决办法?

【问题讨论】:

苹果开发者论坛:forums.developer.apple.com/thread/20017 这个答案可能会帮助其他有同样问题的人:***.com/a/38206546/1137246 【参考方案1】:

好的,I have found out the solution。唯一需要的是在 UITableView 的呈现实例上设置该标志 cellLayoutMarginsFollowReadableWidth

myTableView.cellLayoutMarginsFollowReadableWidth = NO;

我想在文档中找到一些参考,但它似乎还没有准备好,only mentioned on diff page。

由于在 iOS 9 中引入了该标志是为了向后兼容,您应该在尝试设置它之前添加一个检查:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])

    myTableView.cellLayoutMarginsFollowReadableWidth = NO;

Swift 2.0可以使用#available查看iOS版本。

if #available(iOS 9, *) 
    myTableView.cellLayoutMarginsFollowReadableWidth = false

另外你需要用Xcode 7或以上编译它。

编辑

请记住,如果您的分隔符在 iOS 8 中看起来“很好”,这是唯一需要的修复,否则您需要进行更多更改。您可以在 SO 上找到如何执行此操作的信息。

【讨论】:

谢谢!是否有任何选项可以为整个应用关闭此功能,还是我必须手动更新所有 TableViewController 属性? 您是否考虑过为 tableview 创建一个基类(在此处设置)并尽可能使用它?此外,我会看看它是否可以通过外观设置。 是的,这就是我现在正在做的事情(基类方法)我只是想知道是否会有某种“全局开关”来完全关闭它。我尝试了外观的东西,但这不适用于[[UITableView appearance] setCellLayoutMarginsFollowReadableWidth:NO]; 也许这可能是下一个 SO 问题,如何(如果可能)在全局范围内设置它:) 似乎对 iOS 9.1 没有任何影响。【参考方案2】:

如果您想在界面生成器中执行此操作。默认分隔符插入为Automatic。通过选择下拉菜单将其更改为 custom

【讨论】:

“分隔符插入”默认为自动,在更改为自定义之前不显示左/右。【参考方案3】:

Swift 2.2 iOS 9.3

在 viewDidLoad 中

tableView.cellLayoutMarginsFollowReadableWidth = false

在 UITableViewDelegates 中

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) 
    if cell.respondsToSelector(Selector("setSeparatorInset:"))
        cell.separatorInset = UIEdgeInsetsZero
    
    if cell.respondsToSelector(Selector("setPreservesSuperviewLayoutMargins:")) 
        cell.preservesSuperviewLayoutMargins = false
    
    if cell.respondsToSelector(Selector("setLayoutMargins:"))
        cell.layoutMargins = UIEdgeInsetsZero
    

【讨论】:

【参考方案4】:

iOS 9 的完美解决方案

在 viewDidLoad 中

- (void)viewDidLoad 
    [super viewDidLoad];
    //Required for iOS 9
    if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 9.0) 
        self.testTableView.cellLayoutMarginsFollowReadableWidth = NO;
    

在 TableViewDelegate 方法中添加以下代码:

- (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];
    

【讨论】:

首先,如果您从 SO 上的其他答案复制代码,那么如果您提及原始作者并附上其答案的链接(这将是公平的),那就太好了。其次,您可以检查对象是否响应选择器,而不是检查 iOS 版本。 @JulianKról 您对选择器的响应是正确的,它是一种替代方法。这是我的解决方案,我也为此创建了一个演示项目,并且在所有 iOS 版本上都能正常工作。如果你能感激,那感觉真的很棒。 是的,但是我已经在 SO 上看到了具有相同 cmets 等的代码的第二部分。此外,使每件事都变得粗体和斜体也不会提高其可读性 :) 此外,关于 iOS 的问题是明确的9 假设直到 iOS 8 一切都已经完成(这计入你答案的第二部分)。感谢您的参与,但我正在向您提供反馈 是的,这实际上是我在 iOS 8 之前使用的。但是对于 iOS 9,除了此代码之外,还必须设置 self.testTableView.cellLayoutMarginsFollowReadableWidth = NO 。因此,对于正确的答案,我已经提到了完整的代码。 如何链接到 SO 上的原始答案?你什么都没说:)【参考方案5】:

Swift 3.0 / 4.0

tableView.cellLayoutMarginsFollowReadableWidth = false

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: UIView.preservesSuperviewLayoutMargins)) 
        cell.preservesSuperviewLayoutMargins = false
    
    if cell.responds(to: #selector(setter: UIView.layoutMargins)) 
        cell.layoutMargins = UIEdgeInsets.zero
    

【讨论】:

【参考方案6】:

根据此处的不同答案,我可以使用 Swift 中的这些代码行来消除分隔符中的间隙:

tableView.separatorInset = UIEdgeInsetsZero
tableView.layoutMargins = UIEdgeInsetsZero
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero

但我在正文之前仍然有这个小间隙:

【讨论】:

作为一种解决方法,我只是将-14 的约束设置为UITableView,而不是使用上述代码手动对齐表格。【参考方案7】:

这在 iOS 9 中非常适合我。

对于OBJ-C

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(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];
        
         return cell;
    

【讨论】:

【参考方案8】:

接受的答案对我不起作用。直到我在setLayoutMargins 之前移动了setCellLayoutMarginsFollowReadableWidth(iOS 8 仍然需要):

if([_tableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)]) 
  _tableView.cellLayoutMarginsFollowReadableWidth = NO;


if ([_tableView respondsToSelector:@selector(setLayoutMargins:)]) 
  _tableView.layoutMargins = UIEdgeInsetsZero;

【讨论】:

这就是我需要的!顺序很重要。对我来说,我注意到顺序对于横向的 iPad 表格视图很重要。一旦旋转它就固定了,但第一眼看到桌子就错了。谢谢!【参考方案9】:
- (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];
    


【讨论】:

不是我的情况。这在 iOS 8 之前运行良好。 iOS 9 似乎还需要其他东西。【参考方案10】:

适用于 iOS 8 和 9

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    if ([UITableView instancesRespondToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) [cell setLayoutMargins:UIEdgeInsetsZero];

【讨论】:

【参考方案11】:

这是我在 XCode 8.2.1 中针对 Swift 3.0/iOS 10 的解决方案。

我为 UITableview 创建了一个子类,它适用于 IB 并以编程方式创建表视图。

import UIKit

class EXCSuperTV: UITableView

    required init?(coder aDecoder: NSCoder)
    
        super.init(coder: aDecoder)
        setupView()
    

    override init(frame: CGRect, style: UITableViewStyle)
    
        super.init(frame: frame, style: style)
        setupView()
    

    func setupView() 


class EXCNoFooter: EXCSuperTV

    override func setupView()
    
        super.setupView()
        //tableFooterView = UIView.Zero()
    



class EXCMainTV: EXCNoFooter

    override func setupView()
    
        super.setupView()
        separatorInset = UIEdgeInsets.zero
    

【讨论】:

以上是关于iOS 9 UITableView 分隔符插入(显着的左边距)的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 7 iOS 9 UITableViewCell 分隔符插入问题

SwiftUI - 列表行分隔符插入,如 iOS 设置应用程序

UITableView 分隔符插入参考在情节提要中不起作用

iOS 7 中的 UITableView 分隔符颜色是啥?

iOS7上的UITableView分隔符颜色错误

iOS 7.1 中未显示 UITableView 选定的单元格分隔符