动态更改UITableView高度

ale*_*lex 62 height dynamic uitableview ios

我想基于其单元格高度的总和从另一个viewcontroller更改tableview的高度,因为它们是动态的.它可能吗?谢谢

添加在:

我基本上拥有一个UserProfileViewController,它在屏幕的一半上有一个容器视图.在那里我添加了不同的其他viewcontrollers:

在此输入图像描述

在此输入图像描述

在wall按钮的情况下,这是我添加viewcontroller的方式,它是后续的tableview:

- (IBAction)wallButtonPressed:(id)sender
{
    //Check if there is an instance of the viewcontroller we want to display. If not make one and set it's tableview frame to the container's view bounds
    if(!_userWallViewController) {
        self.userWallViewController = [[WallViewController alloc] init];
//        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;

    }

    [self.userWallViewController.containerView addSubview:self.userWallViewController.activityFeedTableView];
    //If the currentviewcontroller adn it's view are already added to the hierarchy remove them
    [self.currentViewController.view removeFromSuperview];
    [self.currentViewController removeFromParentViewController];

    //Add the desired viewcontroller to the currentviewcontroller
    self.currentViewController = self.userWallViewController;

    //Pass the data needed for the desired viewcontroller to it's instances
    self.userWallViewController.searchURLString = [NSString stringWithFormat:@"event/user/%@/", self.userID];
    self.userWallViewController.sendCommentURLString = [NSString stringWithFormat:@"event/message/%@", self.userID];

    [self.userWallViewController.activityFeedTableView reloadData];

    self.userWallViewController.totalCellHeight = ^(float totalCellHeight){

        self.scrollView.contentSize = CGSizeMake(320.0, totalCellHeight);
        CGRect newFrame = self.userWallViewController.containerView.frame;
        newFrame.size.height = totalCellHeight + 33.0;
        self.userWallViewController.containerView.frame = newFrame;

        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;
    };

    //Add this containerview to the desired viewcontroller's containerView
    self.userWallViewController.containerView = self.containerView;


    //Add the needed viewcontroller and view to the parent viewcontroller and the containerview
    [self addChildViewController:self.userWallViewController];
    [self.containerView addSubview:self.userWallViewController.view];

    //CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS
    [self.userFansViewController.userSimpleTableView removeFromSuperview];
    [self.fanOfViewController.userSimpleTableView removeFromSuperview];
    [self.userPublishedMovellaListViewController.gridView removeFromSuperview];

    [self.userPublishedMovellaListViewController removeFromParentViewController];

    self.userPublishedMovellaListViewController = nil;
}
Run Code Online (Sandbox Code Playgroud)

在那个viewcontroller中,这是我初始化tableview的地方:

-(UITableView *)activityFeedTableView
{
    if (!_activityFeedTableView) {
        _activityFeedTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 850.0) style:UITableViewStylePlain];
    }
    return _activityFeedTableView;
}
Run Code Online (Sandbox Code Playgroud)

我正在计算单元格高度的总和,问题是在调用te tableview的getter之后调用单元格的高度方法.因此,我需要某种方式来了解何时为所有细胞完成细胞的高度方法,然后我可以调整我的tableview.谢谢

Rob*_*Rob 174

没有系统功能可以根据tableview的内容更改表的高度.话虽如此,可以基于内容以编程方式更改tableview的高度,具体地基于contentSizetableview的高度(这比自己手动计算高度更容易).一些细节取决于您是否使用iOS 6中的新自动布局.

但假设您正在配置表视图的基础模型viewDidLoad,如果您想调整tableview的高度,可以在viewDidAppear以下位置执行此操作:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self adjustHeightOfTableview];
}
Run Code Online (Sandbox Code Playgroud)

同样,如果您reloadData为tableview 执行(或以其他方式添加或删除行),您还需要确保也手动调用adjustHeightOfTableView,例如:

- (IBAction)onPressButton:(id)sender
{
    [self buildModel];
    [self.tableView reloadData];

    [self adjustHeightOfTableview];
}
Run Code Online (Sandbox Code Playgroud)

所以问题是我们应该adjustHeightOfTableview怎么做.不幸的是,这是您是否使用iOS 6自动布局的功能.您可以通过打开故事板或NIB来确定是否已打开自动布局,然后转到"文件检查器"(例如,按option+ command+ 1或单击右侧面板上的第一个选项卡):

在此输入图像描述

让我们假设自动布局关闭了一秒钟.在这种情况下,它非常简单,adjustHeightOfTableview只需调整frametableview:

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the frame accordingly

    [UIView animateWithDuration:0.25 animations:^{
        CGRect frame = self.tableView.frame;
        frame.size.height = height;
        self.tableView.frame = frame;

        // if you have other controls that should be resized/moved to accommodate
        // the resized tableview, do that here, too
    }];
}
Run Code Online (Sandbox Code Playgroud)

但是,如果启用了自动布局,adjustHeightOfTableview则会调整tableview的高度约束:

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the height constraint accordingly

    [UIView animateWithDuration:0.25 animations:^{
        self.tableViewHeightConstraint.constant = height;
        [self.view setNeedsUpdateConstraints];
    }];
}
Run Code Online (Sandbox Code Playgroud)

对于后一种基于约束的解决方案来使用自动布局,我们必须首先处理一些事情:

  1. 通过单击此处按钮组中的中心按钮确保您的tableview具有高度约束,然后选择添加高度约束:

    添加高度约束

  2. 然后IBOutlet为该约束添加一个:

    添加IBOutlet

  3. 确保调整其他约束,以便在以编程方式调整大小tableview时不会发生冲突.在我的示例中,tableview有一个尾随空间约束,将其锁定到屏幕的底部,因此我必须调整该约束,以便不是被锁定在特定大小,而是可以大于或等于一个值,并且具有较低优先级,以便tableview的高度和顶部将统治当天:

    调整其他约束

    你在这里做的其他约束将完全取决于你在桌面视图下面的屏幕上的其他控件.与往常一样,处理约束有点尴尬,但它确实有效,尽管你的情况中的细节完全取决于你在场景中的其他东西.但希望你能得到这个想法.底线,自动布局,确保调整您的其他约束(如果有),以灵活地考虑更改tableview高度.

如您所见,如果您不使用自动布局,以编程方式调整tableview的高度要容易得多,但如果您使用自动布局,我会提供两种选择.

  • 哇.那一定是我收到的最好的结构化答案.非常感谢.问题是我的应用程序也支持ios 5,所以我不能真正使用该功能,即使我很高兴我从你的答案中学到了一些东西.我已经更新了我的问题.你能看一下吗?谢谢 (4认同)

Moh*_*mar 20

通过xib或storyboard创建您的单元格.给出它的出口内容.现在在CellForRowAtIndexPath中调用它.例如.如果要根据Comment的标签文本设置单元格高度. 在此输入图像描述

所以设置你的commentsLbl.numberOfLine = 0;在此输入图像描述

所以设置你的commentsLbl.numberOfLine = 0;

然后在ViewDidLoad中

 self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;
Run Code Online (Sandbox Code Playgroud)

现在

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}
Run Code Online (Sandbox Code Playgroud)


Lim*_*Red 10

这里的许多答案都不尊重桌子的变化或太复杂.使用autolayout时,使用UITableView正确设置的子类intrinsicContentSize是一个更容易的解决方案.不需要高度限制等.

class UIDynamicTableView: UITableView
{
    override var intrinsicContentSize: CGSize {
        self.layoutIfNeeded()
        return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height)
    }

    override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
    }
} 
Run Code Online (Sandbox Code Playgroud)

UIDynamicTableView在接口构建器中设置TableView的类并观察魔法,因为此TableView将在调用后更改其大小reloadData().

  • 真棒的答案!我好几天都在寻找这个解决方案.希望我能投票5到6次. (2认同)
  • 可能的改进:`高度:self.contentSize.height + self.contentInset.top + self.contentInset.bottom` (2认同)

Jus*_*ely 7

只需在viewDidAppear中使用一行代码即可大大简化:

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

Rob的解决方案非常好,只有在他的-(void)adjustHeightOfTableview方法中才能调用

[self.view needsUpdateConstraints]
Run Code Online (Sandbox Code Playgroud)

什么都不做,它只返回一个标志,而不是呼叫

[self.view setNeedsUpdateConstraints]
Run Code Online (Sandbox Code Playgroud)

会产生预期的效果.