在 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
}
奇怪的东西。
我正在尝试在 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
}
奇怪的东西。