我想设置UITableView以匹配表视图中所有内容的高度。
这是我的故事板
这个问题是顶部和底部的ImageView在屏幕上始终是静态的。
假设桌面视图中有10个项目,但由于屏幕尺寸限制,只有7个项目显示。我希望在用户能够看到底部的ImageView之前显示所有10个。 (顺便说一下,所有3个视图,即图像视图和tableview都在uiscrollview中)
IDEAL
我必须处理的一些其他限制是表视图中的项目数是动态的,这意味着它可以是任何通常小于10的数量,我稍后将从api中检索。根据内容,细胞高度也是动态的。
我刚刚开始使用一些简单的代码
class ExampleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var items: [String] = [
"Item 01", "Item 02", "Item 03", "Item 04", "Item 05",
"Item 06", "Item 07", "Item 08", "Item 09", "Item 10"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
}
答案 0 :(得分:10)
将您的UITableView子类化以将intrinsicContentSize重写为其contentSize,如下所示:
override var intrinsicContentSize: CGSize {
return contentSize
}
然后为您的表使用自动行高,因此您的exampleViewController的viewDidLoad将具有:
tableView.estimatedRowHeight = 44
UITableViewDelegate函数:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
当您从API接收数据并重新加载表格时,只需致电:
tableView.invalidateIntrinsicContentSize()
这将告诉您的表格将其自身调整为与其内容相同的大小(因为覆盖),并根据需要移动底部图像。
如果你的故事板发出错误,说UIScrollView的高度不明确,因为UITableView上没有高度限制,请选择你的UITableView并在Size Inspector中给它一个占位符内在大小。
答案 1 :(得分:4)
您需要将IBOutlet设置为设置NSLayoutConstraint
高度的tableView
(首先需要使用任何值创建高度约束,无关紧要)然后按住Ctrl键将其拖动到您的班级文件
然后在您的viewWillAppear
中,您必须计算tableView
高度并进行设置。像这样:
var tableViewHeight:CGFloat = 0;
for (var i = tableView(self.tableView , numberOfRowsInSection: 0) - 1; i>0; i-=1 ){
tableViewHeight = height + tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: i, inSection: 0) )
}
tableViewHeightLayout.constant = tableViewHeight
这就是它。这将为您提供scrollView内容大小,不应引发任何警告。
答案 2 :(得分:2)
使用子分类技术的答案不完整。您还应该像这样覆盖layoutSubviews()
。
public class DynamicSizeTableView: UITableView
{
override public func layoutSubviews() {
super.layoutSubviews()
if bounds.size != intrinsicContentSize {
invalidateIntrinsicContentSize()
}
}
override public var intrinsicContentSize: CGSize {
return contentSize
}
}
答案 3 :(得分:2)
这是我在生产应用中使用的:
斯威夫特 5,2021 年
import UIKit
class DynamicTableView: UITableView {
/// Will assign automatic dimension to the rowHeight variable
/// Will asign the value of this variable to estimated row height.
var dynamicRowHeight: CGFloat = UITableView.automaticDimension {
didSet {
rowHeight = UITableView.automaticDimension
estimatedRowHeight = dynamicRowHeight
}
}
public override var intrinsicContentSize: CGSize { contentSize }
public override func layoutSubviews() {
super.layoutSubviews()
if !bounds.size.equalTo(intrinsicContentSize) {
invalidateIntrinsicContentSize()
}
}
}
答案 4 :(得分:1)
在这种情况下,不要让你的底部单元格成为静态,使其成为表格视图的一部分,并使用表格视图委托方法在最后一行插入此底部图像 - Class
答案 5 :(得分:1)
在这种情况下,在表格页脚视图中添加底部imageView(红色)。
要在UITableView
中添加页脚视图,您可以使用:
tableViewObj.tableFooterView = footerViewObj;
答案 6 :(得分:1)
您可能必须实现表视图内在内容大小。请检查此answer以查看是否有帮助。
我记得有这个问题,甚至创建了一个自定义的UITableView
子类。
#import "IntrinsicTableView.h"
@implementation IntrinsicTableView
#pragma mark - UIView
- (CGSize)intrinsicContentSize
{
return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}
#pragma mark - UITableView
- (void)endUpdates
{
[super endUpdates];
[self invalidateIntrinsicContentSize];
}
- (void)reloadData
{
[super reloadData];
[self invalidateIntrinsicContentSize];
}
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
[super reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
[super reloadSections:sections withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
[super insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
[super insertSections:sections withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
[super deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
[super deleteSections:sections withRowAnimation:animation];
[self invalidateIntrinsicContentSize];
}
@end
答案 7 :(得分:1)
试试这个
in ViewDidLoad
self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;
索引路径行的高度
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}
答案 8 :(得分:1)
更新Swift 4 这段代码工作得很好
var items = [
"Item 01", "Item 02", "Item 03", "Item 04", "Item 05",
"Item 06", "Item 07", "Item 08", "Item 09", "Item 10"]
tableViewHeightLayout.constant = CGFloat(items.count) *
tableViewHeightLayout.constant
yourtableView.layoutIfNeeded()
答案 9 :(得分:0)
基于Xamarin编写的解决方案@nikans
[Register(nameof(DynamicSizeTableView)), DesignTimeVisible(true)]
public class DynamicSizeTableView : UITableView
{
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (Bounds.Size != IntrinsicContentSize)
InvalidateIntrinsicContentSize();
}
public override CGSize IntrinsicContentSize => ContentSize;
public DynamicSizeTableView(CGRect frame) : base(frame) { }
public DynamicSizeTableView(IntPtr handle) : base(handle) { }
}
答案 10 :(得分:0)
更新Swift5。添加maxHeight,以便您可以指定tableView的高度
class SelfSizingTableView: UITableView {
var maxHeight = CGFloat.infinity
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
setNeedsLayout()
}
}
override var intrinsicContentSize: CGSize {
let height = min(maxHeight, contentSize.height)
return CGSize(width: contentSize.width, height: height)
}
}
答案 11 :(得分:0)
这里很简单。
第一步:为table view设置高度约束
第 2 步:控制拖动约束
第 3 步: 在返回行数之前。在 numberOfRowsInSection 方法中,做
tableViewHeightConstraint.constant = tableView.rowHeight * CGFloat(someArray.count)
答案 12 :(得分:-1)
基于@ rr1g0的解决方案
为tableView创建高度约束并为其创建出口。在 viewDidLayoutSubviews()中,使用以下代码:
var tableViewHeight: CGFloat = 0
for section in 0..<tableView.numberOfSections {
for row in 0..<tableView.numberOfRows(inSection: section) {
tableViewHeight += tableView(tableView, heightForRowAt: IndexPath(row: row, section: section))
}
}
tableViewHeightConstraint.constant = tableViewHeight