在 Swift 中设置 tableView header 的高度

Setting tableView header's height in Swift

我正在尝试在 table 视图控制器中设置位于原型单元格顶部的视图的高度。我使用 IB 来设置它的高度(尺寸检查器)并将其设置为 61(绿色视图是 'header' 视图):

但是每当我 运行 应用程序时,它的高度最终会变成 568.0。我的 table 视图控制器中的视图有一个名为 testUIView 的 IBOutlet,我这样做:println("testUIView Height->\(testUIView.frame.height)") 并且最终在 运行 时成为 568.0

这是显示其在 运行 时间的高度的屏幕截图:

所以我的问题是:如何设置视图的高度,使其在 运行 时为 61,这样它确实看起来像我的第一个屏幕截图 (size-wise)?

我试图在 override func viewWillLayoutSubviews() 内设置它的高度 属性 但它不允许我为高度 testUIView.frame.height = CGFloat(61.0) 赋值。

感谢任何帮助!提前致谢!

干杯!

这是一个解决方案,它使用 部分 header 视图 而不是实际的 table header 查看:


如果您想为 UITableView 使用 header,您可以在 Interface Builder 中设计另一个原型单元格,基于 UITableViewCell 创建自定义 class 并将其分配给原型class 检查器上界面生成器中的单元格。

然后在你的控制器中你将使用

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

在该函数中,您实际上将从 table 视图创建一个可重复使用的单元格,但将其转换为您为 header 创建的自定义单元格。您将可以像访问常规 UITableViewCell 一样访问它的所有属性,然后您只需转到 return 单元格的视图

return cell.contentView

您将要使用的另一种方法是

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}

这个是不言自明的。

Swift 3.0.1

public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}

Swift 3/Xcode 8:

viewDidLoad()中添加:

let HEADER_HEIGHT = 100
tableView.tableHeaderView?.frame.size = CGSize(width: tableView.frame.width, height: CGFloat(HEADER_HEIGHT))

尽情享受吧!

在 swift 4.1 和 Xcode 9.4.1 中

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
     if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
        return 75.0
      } else {
        return 50.0
      }
}

接受的答案实际上并没有回答问题。相反,它提供了使用 SECTION header 的替代方法。其他人已经回答了这个问题,但我将在此处复制答案并提供更多说明。


正在加载视图

Table 视图与 iPhone 一样古老,因此有时您必须强制它执行您想要的操作。

首先我们需要加载 header 并手动设置它的高度。否则视图将占据比它需要的更高的高度。我们在 viewDidLayoutSubviews 回调中执行此操作:

lazy var profileHeaderView: ProfileHeaderView = {
    let headerView = ProfileHeaderView()
    return headerView
}()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    sizeHeaderToFit()
}

private func sizeHeaderToFit() {
    profileHeaderView.setNeedsLayout()
    profileHeaderView.layoutIfNeeded()

    var frame = profileHeaderView.frame
    frame.size.height = profileHeaderView.calculateHeight()
    profileHeaderView.frame = frame

    tableView.tableHeaderView = profileHeaderView
}

如您所见,我喜欢将我的视图放在惰性变量中。这确保它们始终被创建,但仅在我开始使用它们时才创建。

你也可以看到我在计算高度。在某些情况下,您的高度是固定的,因此您可以将框架高度设置为硬编码值。


设置一些优先级

我们可能会在调试器中看到一些约束警告。出现这种情况是因为 table 视图在使用我们上面指定的大小之前首先强制使用 0x0 大小 此时,您的约束和视图的高度相互冲突。

要清除这些,我们只需设置约束优先级。首先,您应该将 header 视图组件包装在另一个视图中(我通常总是对 header 视图这样做)。这将使您在 header 视图中管理约束变得更加容易。

然后我们需要将底部约束优先级设置为高:

containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

这是一个更完整的例子:

警告:认为它作为布局视图的指南仍然有用,如果您使用 nib 或故事板创建视图,请不要使用此代码。

class ProfileHeaderView: UIView {
    lazy var containerView: UIView = {
        let view = UIView()
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLayout()
    }

    required init?(coder aDecoder: NSCoder) {
        // We do this because the view is not created using storyboards or nibs.
        fatalError("init(coder:) has not been implemented")
    }

    private func setupLayout() {
        self.addSubview(containerView)

        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
        containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

        // Set the rest of your constraints against your containerView not self and add your subviews to your containerView not self
    }
}

这里是使用snap-kit设置约束的例子:

containerView.snp.makeConstraints() { make in
    make.top.equalTo(self.snp.top)
    make.leading.equalTo(self.snp.leading)
    make.trailing.equalTo(self.snp.trailing)
    make.bottom.equalTo(self.snp.bottom).priority(.high)
}

确保将约束添加到 containerView 而不是 self 并使用 containerView 添加子视图和其余约束。

这一定是 iOS 中最奇怪的问题之一。

如果您只想要一个固定的高度,从 2019 年开始您可以:

public override func viewDidLayoutSubviews() {
    var frame = tableView.tableHeaderView!.frame
    frame.size.height = 68
    tableView.tableHeaderView!.frame = frame
}

奇怪的东西。