63

我想根据单元格高度的总和从另一个视图控制器更改我的表格视图的高度,因为它们是动态的。有可能吗?谢谢

添加在:

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

在此处输入图像描述

在此处输入图像描述

在墙壁按钮的情况下,这是我添加视图控制器及其后续表格视图的方式:

- (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 之后调用单元格的高度方法。所以我需要某种方法来知道何时对所有单元格完成单元格的高度方法,然后我可以调整我的表格视图的大小。谢谢

4

8 回答 8

174

没有系统功能可以根据表格视图的内容更改表格的高度。话虽如此,可以根据内容以编程方式更改 tableview 的高度,特别是基于contentSizetableview 的高度(这比自己手动计算高度更容易)。一些细节会有所不同,具体取决于您是否使用作为 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 并转到“文件检查器”来确定是否打开了自动布局(例如,按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
    }];
}

但是,如果您的自动布局打开,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];
    }];
}

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

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

    添加高度约束

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

    添加 IBOutlet

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

    调整其他约束

    您在此处使用其他约束做什么将完全取决于您在表格视图下方的屏幕上拥有的其他控件。与往常一样,处理约束有点尴尬,但它确实有效,尽管你的具体情况完全取决于你在现场还有什么。但希望你能明白。最重要的是,使用自动布局,请确保调整您的其他约束(如果有)以灵活地考虑变化的 tableview 高度。

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

于 2013-01-09T03:51:57.100 回答
21

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

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

所以设置你 commentsLbl.numberOfLine=0;

然后在 ViewDidLoad

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

现在

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}
于 2015-05-19T14:21:40.403 回答
10

这里的很多答案都不尊重表格的变化或者太复杂了。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()
    }
} 

在界面构建器中将您的 TableView 的类设置为UIDynamicTableView并观察魔术,因为此 TableView 将在调用reloadData().

于 2017-01-17T03:06:50.367 回答
8

这可以通过 viewDidAppear 中的 1 行代码来大大简化:

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

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }
于 2016-05-11T15:54:44.153 回答
5

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

[self.view needsUpdateConstraints]

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

[self.view setNeedsUpdateConstraints]

会产生想要的效果。

于 2014-04-25T13:35:20.893 回答
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: 来做这件事,但这真的不是一个好方法。有任何想法吗?

于 2013-01-14T13:02:25.120 回答
2

使用简单易行的代码

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

        return heightForCell;
    }
于 2015-12-30T11:12:49.807 回答
0

我发现以编程方式添加约束比在情节提要中容易得多。

    var leadingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.LeadingMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: 0.0)

    var trailingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: mView, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1, constant: 0.0)

    var height = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screenSize.height - 55)

    var bottom = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.BottomMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1, constant: screenSize.height - 200)

    var top = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.TopMargin, multiplier: 1, constant: 250)

    self.view.addConstraint(leadingMargin)
    self.view.addConstraint(trailingMargin)
    self.view.addConstraint(height)
    self.view.addConstraint(bottom)
    self.view.addConstraint(top)
于 2015-10-06T08:05:06.787 回答