【问题标题】:Dynamic cell height in iOS 7 and iOS 8 - can I only support heightForRowAtIndexPath in iOS 7?iOS 7 和 iOS 8 中的动态单元格高度 - 我只能在 iOS 7 中支持 heightForRowAtIndexPath 吗?
【发布时间】:2015-03-13 03:36:02
【问题描述】:

我有一个带有动态大小单元格的表格视图。这在 iOS 8 中效果很好,但在 iOS 7 中不受支持。我需要实现 tableView:heightForRowAtIndexPath 否则应用程序将在 iOS 7 中崩溃。如果这样做,我将不得不计算单元格的高度.问题是,如果我实现这个方法,iOS 8 会注意它,而不再使用它的动态大小的单元格魔法。有没有办法只为 iOS 7 客户端实现这个方法?

【问题讨论】:

    标签: ios uitableview ios7 ios8 autolayout


    【解决方案1】:

    我以前用过类似的东西:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:@"CellIdentifier"];
    
        // Stuff & Things
    
        [cell.contentView setNeedsLayout];
        [cell.contentView layoutIfNeeded];
    
        return [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    }
    

    【讨论】:

    • Swift,这确实有效,但前提是你为单元格而不是 contentView > cell.setNeedsLayout() > cell.layoutIfNeeded() 一些 ios7 兼容性不会伤害任何人 =D跨度>
    【解决方案2】:

    iOS 8 中新的内部自动布局自动调整大小的单元格无法神奇地反映到 iOS 7 中。但这不是问题。如果您想向后兼容 iOS 7,那么正如您所说的那样,这意味着您将自己确定单元格高度,以便您可以从 tableView:heightForRowAtIndexPath: 返回正确的值。这就是我们在 iOS 4、5、6 和 7 中所做的。这在 iOS 8 中仍然有效(而且可能更快)。

    所以我的建议是:就像为 iOS 7 编写代码一样。如果你在 Objective-C 中编写代码,可能有两组不同的代码(条件编译),甚至在 Swift 中,您可以使用两个不同的类,这取决于我们发现自己所处的系统;但我认为这有点过头了——这是一场等待发生的代码维护噩梦。

    【讨论】:

    • 谢谢,我想我试图两全其美,让 iOS 8 使用它的魔力,而在此之前的任何东西都使用 heightForRowAtIndexPath。听起来那是不可能的..
    • 这是可能的,但(在我看来)不值得麻烦。我会在我的答案中添加一些东西......
    • 这不是一个真正的答案。这种方法的条件编译如何工作?这就是问题的答案。而且这似乎不是一个不合理的问题,仅仅因为过去比较困难并不意味着现在不值得走捷径来使用新的 API。例如,您可能希望返回 ios7 的硬编码或估计值,以便应用程序仍然运行,但不要花时间让细微的自动布局大小差异完美运行,因为此时 ios7 用户群远小于 ios8
    • @danny 它一个答案:这是我的答案。这就是我所做的:如果我的应用程序要向后兼容,我会继续在heightForRow... 的实现中使用systemLayoutSizeFittingSize:,并使用内部约束来确定单元格高度。它适用于 iOS 7 和 iOS 8,事实上,“新”iOS 8 功能正在做的一切!我已经在我的书中充分解释了这种技术。因此,如果您有不同的答案,请给出。但是不要告诉我我的答案是没有答案。这是一个很好的答案。
    【解决方案3】:

    我在调试日志中收到UIViewAlertForUnsatisfiableConstraints 错误。

    无法同时满足约束。以下列表中的至少一个约束可能是您不想要的。试试这个:(1)查看每个约束并尝试找出您不期望的; (2) 找到添加了一个或多个不需要的约束的代码并修复它。 (注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)(“”、“”、“”)

    如果没有tableView:heightForRowAtIndexPath:,则单元格看起来很好。所以,我想在 iOS 8 中禁用它。@batu 在另一篇文章中给出了解决方案:Implement heightForRowIndexPath: in iOS 7, but remove it in iOS 8 using compile-time macro。感谢@batu,解决方案就这么简单:

    #define IS_IOS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    
    -(CGFloat) tableView: (UITableView * ) tableView heightForRowAtIndexPath: (NSIndexPath * ) indexPath {
      if (IS_IOS_8_OR_LATER) {
        return UITableViewAutomaticDimension;
      }
      // Your iOS 7 code here.
    }
    

    但是,我的单元格在 iOS 8 和 iPhone 6 中的高度仍然存在问题。原因似乎是 UILabel 的固定宽度(设计用于 320pt )。这是我经过漫长的一夜研究后所做的:

    1. 我应用了本指南中的解决方案:Dynamic Table View Cell Height and Auto Layout

    2. 由于 UILabel 需要 iOS 7 设备的显式宽度,因此我以编程方式“清除”了 iOS 8 的此设置。在我的扩展表格视图单元格中:

      - (void)awakeFromNib {
          // Initialization code
          if (IS_IOS_8_OR_LATER) {
              self.descriptionLabel.preferredMaxLayoutWidth = 0;
          }
      }
      
    3. 我使用了指南中的RWLabel 建议。

    4. 禁用return UITableViewAutomaticDimension;。是启用还是禁用,可能取决于表格视图单元格中的子视图和约束。尽量适应你的情况。

    5. 我将所有 RWLabel 的尾随空格的优先级更改为 999(而不是 1000)。这消除了不可满足的约束警告。

    希望这些解决方案对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多