【问题标题】:How to properly set a dynamic header view in table view?如何在表格视图中正确设置动态标题视图?
【发布时间】:2018-06-30 08:36:37
【问题描述】:

我需要一个部分的标题视图是一个UIImageView,下面是一个UILabel。图像视图的高度在创建后不会改变,但标签中的文本可能会由于某些用户操作而改变。我需要动态更新整个标题视图的高度(使用 AutoLayout,而不是更改框架)。

我一直在查看一些帖子,例如 this one,但我尝试的解决方案对我不起作用。当我更改标签中的文本时,我的标题视图的高度没有更新。

也许我需要从一开始就了解它是如何工作的。首先,我想明确一点:

  1. tableView(_:viewForHeaderInSection:) 中将标题视图作为UIView 的子类提供与将其作为UITableViewHeaderFooterView 的子类提供并将其注册到表视图有什么区别?

  2. header 视图中的子视图需要哪些约束才能具有动态高度?

  3. 应该如何动态更新header view的高度?

【问题讨论】:

    标签: ios swift uitableview autolayout uitableviewsectionheader


    【解决方案1】:

    我相信这很简单:

    1. 设置tableView:

      tableView.estimatedSectionHeaderHeight = 63
      tableView.sectionHeaderHeight = UITableViewAutomaticDimension
      
    2. 实现您的自定义部分标题并在委托方法中返回它:

      override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      
          switch section {
          case 0:
              return sectionHeader
      
          default:
              fatalError("Unreachable code")
          }
      }
      
    3. 最后,如果标题部分中的内容在显示标题时发生更改,则更改后您必须告诉tableView 重新绘制自己使用:

      // method in the tableViewController
      func refreshTableAfterCellExpansion() {
          self.tableView.beginUpdates()
          self.tableView.setNeedsLayout()
          self.tableView.endUpdates()
      }
      

    【讨论】:

    • 谢谢,那么tableView(_:heightForHeaderInSection:) 方法应该返回什么?我看到它在tableView(_:viewForHeaderInSection:) 之前被调用
    • @AppsDev 只有在实现时才应该调用它,所以要么完全删除它,要么返回UITableViewAutomaticDimension。我个人更喜欢干脆不实现它(该方法在UITableViewDelegate中应该是可选的,所以你不必实现它)
    【解决方案2】:

    您可能想要使用如下所示的功能。调整属性以适合您用于标签的字体和字体大小:

    func handleEstimatedFrameForText(_ text: String) -> CGRect {
        let size = CGSize(width: 200, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font: UIFont(name: "AvenirNext-Medium", size: 16) as Any], context: nil)
    }
    

    当您使用该方法设置标题的大小时,您想使用此函数获取UILabel AFTER 文本添加后的高度,然后添加和填充类型,UIImageView身高等

    在设置标题大小的方法中

     var height: CGFloat = 0
        let headerMessage = messages[indexPath.item]
        if let labelText = headerMessage.text {
            let headerImageViewHeight: CGFloat = 80 /* ADD IN YOUR UIIMAGEVIEW HEIGHT */
            height = self.handleEstimatedFrameForText(labelText).height + headerImageViewHeight
            return CGSize(width: view.frame.width, height: height)
        } else {
            return CGSize(width: view.frame.width, height: 200) /* DEFAULT SIZE */
        }
    

    您可能需要向self.handleEstimatedFrameForText(labelText).height + headerImageViewHeight 添加额外的几个像素,因为某些字体需要额外的 12 个像素左右才能在所有设备上运行。反复试验。

    【讨论】:

    • 谢谢,但这是我试图避免的,不得不“手动”计算标题的高度......难道不能简单地依靠 AutoLayout 来实现它吗?跨度>
    猜你喜欢
    • 2015-07-03
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多