Change UITableView height dynamically

2019-01-02 14:24发布

I want to change the height of my tableview from another viewcontroller based on the sum of its cells' heights, as they are dynamic. Is it at all possible? Thanks

Add-on:

What I basically have is a UserProfileViewController that has a containerview on half of the screen. There I add different other viewcontrollers:

enter image description here

enter image description here

In the case of the wall button this is how I add the viewcontroller and it's subsequent 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;
}

and in that viewcontroller this is where I initialize my tableview:

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

I am calculating he total sum of the cell's height, the problem is that the cell's height method is called way after the getter of te tableview is called. So I would need some sort of way to know when the cells' height method is done for all cells and then I can resize my tableview. Thanks

8条回答
明月照影归
2楼-- · 2019-01-02 14:50

Rob's solution is very nice, only thing that in his -(void)adjustHeightOfTableview method the calling of

[self.view needsUpdateConstraints]

does nothing, it just returns a flag, instead calling

[self.view setNeedsUpdateConstraints]

will make the desired effect.

查看更多
伤终究还是伤i
3楼-- · 2019-01-02 14:53

for resizing my table I went with this solution in my tableview controller witch is perfectly fine:

[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);
                            }];

The resizing part is in a method but here is just so you can see it. Now the only problem I haveis resizing the scroll view in the other view controller as I have no idea when the tableview has finished resizing. At the moment I'm doing it with performSelector: afterDelay: but this is really not a good way to do it. Any ideas?

查看更多
余生请多指教
4楼-- · 2019-01-02 14:53

I found adding constraint programmatically much easier than in storyboard.

    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)
查看更多
余生无你
5楼-- · 2019-01-02 14:59

create your cell by xib or storyboard. give it's outlet's contents. now call it in CellForRowAtIndexPath. eg. if you want to set cell height according to Comment's label text. enter image description here

so set you commentsLbl.numberOfLine=0;enter image description here

so set you commentsLbl.numberOfLine=0;

then in ViewDidLoad

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

and now

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}
查看更多
步步皆殇っ
6楼-- · 2019-01-02 15:01

Use simple and easy code

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

        return heightForCell;
    }
查看更多
梦寄多情
7楼-- · 2019-01-02 15:03

This can be massively simplified with just 1 line of code in viewDidAppear:

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

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }
查看更多
登录 后发表回答