在Swift中设置tableView标题的高度

时间:2015-07-28 01:21:11

标签: ios swift uitableview uiview

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

header view

但每当我运行应用程序时,它的'身高最终为568.0。我有一个名为testUIView的IBOutlet用于我的表视图控制器中的视图,我做:println("testUIView Height->\(testUIView.frame.height)")并且在运行时确实最终成为568.0

这是一个截图,显示其'运行时的高度:

enter image description here

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

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

任何帮助表示赞赏!提前谢谢!

干杯!

6 个答案:

答案 0 :(得分:51)

如果您想为UITableView使用标题,您可以在Interface Builder中设计另一个原型单元格,根据UITableViewCell创建一个自定义类,并将其分配给类检查器的界面构建器中的原型单元格。

然后在您的控制器中,您将使用

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

在该功能中,您实际上将从表视图中创建可重用的单元格,但是将其强制转换为您为标题创建的自定义单元格。你可以访问它的所有属性,比如常规的UITableViewCell,然后你就可以返回单元格的视图

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
}

答案 1 :(得分:16)

Swift 3 / Xcode 8:

viewDidLoad()

中添加此内容
let HEADER_HEIGHT = 100
tableView.tableHeaderView?.frame.size = CGSize(width: tableView.frame.width, height: CGFloat(HEADER_HEIGHT))

享受!

答案 2 :(得分:1)

在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
      }
}

答案 3 :(得分:0)

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


加载视图

表视图与iPhone一样古老,因此有时必须强制其执行所需的操作。

首先,我们需要加载标题并手动设置其高度。否则,视图的高度将超过所需高度。我们在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
}

如您所见,我喜欢将自己的观点放在惰性变量中。这样可以确保始终创建它们,但仅当我开始使用它们时才可以。

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


设置一些优先级

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

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

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

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

以下是更完整的示例:

警告:以为它仍可作为布局视图的指南,如果使用笔尖或情节提要创建视图,请不要使用此代码。

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添加子视图和其他约束。

答案 4 :(得分:0)

它必须是iOS中最奇怪的问题之一。

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

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

奇怪的东西。

答案 5 :(得分:-1)

简单说一下 Swift 5.0

let HEADER_HEIGHT: CGFloat = 61

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