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

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

【问题讨论】:

标签: ios uitableview uikit xcode7 ios9


【解决方案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
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-10-10
            • 1970-01-01
            • 2016-03-30
            • 2014-11-04
            • 2016-09-29
            • 1970-01-01
            • 2019-11-10
            相关资源
            最近更新 更多