动态更改UITableView高度

时间:2013-01-08 21:00:48

标签: ios uitableview dynamic height

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

附加:

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

enter image description here

enter image description here

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

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

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

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

8 个答案:

答案 0 :(得分:174)

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

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

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

    [self adjustHeightOfTableview];
}

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

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

    [self adjustHeightOfTableview];
}

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

enter image description here

让我们假设自动布局关闭了一秒钟。在这种情况下,它非常简单,adjustHeightOfTableview只会调整tableview的frame

- (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
    }];
}

如果您的自动布局已开启,adjustHeightOfTableview会调整您的桌面视图的高度限制:

- (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];
    }];
}

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

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

    add height constraint

  2. 然后为该约束添加IBOutlet

    add IBOutlet

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

    adjust other constraints

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

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

答案 1 :(得分:20)

通过xib或storyboard创建您的单元格。给出它的出口内容。 现在在CellForRowAtIndexPath中调用它。  例如。如果要根据Comment的标签文本设置单元格高度。 enter image description here

所以设置你的commentsLbl.numberOfLine = 0; enter image description here

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

然后在ViewDidLoad

 self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;

现在

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}

答案 2 :(得分:10)

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

intrinsicContentSize

在界面构建器中将TableView的类设置为class UIDynamicTableView: UITableView { override var intrinsicContentSize: CGSize { self.layoutIfNeeded() return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height) } override func reloadData() { super.reloadData() self.invalidateIntrinsicContentSize() } } 并观察神奇,因为此TableView将在调用UIDynamicTableView后更改其大小。

答案 3 :(得分:6)

这可以通过viewDidAppear中的一行代码进行大规模简化:

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

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }

答案 4 :(得分:5)

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

[self.view needsUpdateConstraints]

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

[self.view setNeedsUpdateConstraints]

会产生预期的效果。

答案 5 :(得分:3)

使用简单易用的代码

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let myCell = tableView.dequeueReusableCellWithIdentifier("mannaCustumCell") as! CustomCell
        let heightForCell = myCell.bounds.size.height;

        return heightForCell;
    }

答案 6 :(得分:2)

为了调整我的表格,我在tableview控制器中使用了这个解决方案,这非常好:

[objectManager getObjectsAtPath:self.searchURLString
                         parameters:nil
                            success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                NSArray* results = [mappingResult array];
                                self.eventArray = results;
                                NSLog(@"Events number at first: %i", [self.eventArray count]);
                                CGRect newFrame = self.activityFeedTableView.frame;
                                newFrame.size.height = self.cellsHeight + 30.0;
                                self.activityFeedTableView.frame = newFrame;

                                self.cellsHeight = 0.0;

                            }
                            failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                                message:[error localizedDescription]
                                                                               delegate:nil
                                                                      cancelButtonTitle:@"OK"
                                                                      otherButtonTitles:nil];
                                [alert show];
                                NSLog(@"Hit error: %@", error);
                            }];

调整大小的部分是一个方法,但这里只是你可以看到它。 现在唯一的问题是我在另一个视图控制器中调整滚动视图的大小,因为我不知道tableview何时完成大小调整。目前我正在使用performSelector:afterDelay:但这实际上不是一个好方法。有什么想法吗?

答案 7 :(得分:0)

我发现以编程方式添加约束比在故事板中更容易。

height
相关问题