ios 在 Swift 中设置 tableView 标题的高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31665927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:01:21  来源:igfitidea点击:

Setting tableView header's height in Swift

iosswiftuitableviewuiview

提问by idelara

I am trying to set the height of a view that is on top of my prototype cell in a table view controller. I use IB to set it's height (size inspector) and set it to 61 like so (the green view is the 'header' view):

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

header view

标题视图

But whenever I run the app, its' height ends up being 568.0. I have an IBOutlet called testUIViewfor the view in my table view controller, and I do: println("testUIView Height->\(testUIView.frame.height)")and indeed ends up being 568.0at runtime.

但是每当我运行该应用程序时,它的高度最终都是568.0. 我有一个 IBOutlettestUIView在我的表视图控制器中调用视图,我这样做了:println("testUIView Height->\(testUIView.frame.height)")并且确实最终568.0在运行时。

Here is a screenshot showing its' height at runtime:

这是一个屏幕截图,显示了它在运行时的高度:

enter image description here

在此处输入图片说明

So my question is: How can I set the view's height so it is 61 at runtime so it indeed looks like my first screenshot (size-wise)?

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

I tried to set its' height property inside override func viewWillLayoutSubviews()but it did not let me assign a value to the height testUIView.frame.height = CGFloat(61.0).

我试图在里面设置它的 height 属性,override func viewWillLayoutSubviews()但它没有让我为 height 分配一个值testUIView.frame.height = CGFloat(61.0)

Any help is appreciated! Thanks in advance!

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

Cheers!

干杯!

回答by Fred Faust

Here is a solution which uses section header viewsrather than the actual table header view:

这是一个使用部分标题视图而不是实际表标题视图的解决方案:



If you'd like to use a header for you UITableView instead you can design another prototype cell in Interface Builder, make a custom class based on a UITableViewCell and assign it to the prototype cell in interface builder on the class inspector.

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

Then in your controller you're going to use

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

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

In that function you're actually going to create a reusable cell from your table view but cast as the custom cell you made for the header. You will have access to all of it's properties like a regular UITableViewCell, then you're just going to return the cell's view

在该函数中,您实际上将从表格视图中创建一个可重用的单元格,但将其转换为您为标题制作的自定义单元格。您将可以像常规 UITableViewCell 一样访问它的所有属性,然后您只需返回单元格的视图

return cell.contentView

Another method you're going to use is

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

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

That one is pretty self explanatory.

那是不言自明的。

Swift 3.0.1

斯威夫特 3.0.1

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

回答by Nick Ivanov

Swift 3/Xcode 8:

斯威夫特 3/Xcode 8:

Add this in viewDidLoad():

将此添加到viewDidLoad()

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

Enjoy!

享受!

回答by iOS

In swift 4.1 and Xcode 9.4.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
      }
}

回答by Kubee

The accepted answer doesn't actually answer the question. It instead offers an alternative by using the SECTION header. This question has been answered by others but I will duplicate the answer here with a few more instructions.

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



Loading the view

加载视图

Table views are as old as iPhones and therefore you sometimes have to force it to do what you want.

表格视图和 iPhone 一样古老,因此有时你不得不强迫它做你想做的事。

First we need to load the header and manually set its height. Otherwise the view will take more height than it needs. We do this on the viewDidLayoutSubviewscallback:

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

As you can see, I like to put my views inside lazy vars. This ensures that they are always created but only when I start using them.

正如你所看到的,我喜欢把我的观点放在惰性变量中。这确保它们总是被创建,但只有当我开始使用它们时。

You can also see that I'm calculating the height. In some cases, your height is fixed and therefore you can just set the frame height to a hardcoded value.

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



Set some priorities

设置一些优先级

We will likely see some constraint warnings appear in our debugger. This happens because the table view first forces a 0x0 size before using the size we specified above At this moment, your constraints and the height of the view are in conflict with each other.

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

To clear these, we simply set the constraint priorities. First you should wrap your header view components inside another view (I generally always do this for header views). This will make managing constraints much easier on your header view.

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

We then need to set the bottom constraint priorities to high:

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

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

Here is a more complete example:

这是一个更完整的例子:

WARNING: Thought it is still useful as a guide for laying out your views, do not use this code if you're creating your views using nibs or storyboards.

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

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

Here is the example of the constraints set using snap-kit:

以下是使用 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)
}

Make sure you add your constraints to the containerViewnot selfand use containerView to add your subviews and rest of your constraints.

确保将约束添加到containerViewnotself并使用 containerView 添加子视图和其余约束。

回答by Fattie

It has to be one of the strangest issues in iOS.

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

If you do just want a fixed height, as of 2019 you can:

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

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

Strange stuff.

奇怪的东西。