简体   繁体   中英

UITableView subview inside UITableViewCell won't display

I'm trying to create a UITableview, where each cell contains another UITableView. It's basically a list of 2-3 rows, where each row then has a sublist of 2-3 rows inside.

The main ViewController behaves just like any other TableViewController, and inside the cellForRowAtIndexPath, it attempts to add a SubTableViewController.view with a dynamic height. The SubTableViewController is the second tableview and each has their own Datasource.

The problem I'm running into is the SubTableViewController appears to render properly using the debugger, with the correct data and number of cells, but it simply isn't appearing when rendering. I noticed it has a contentSize height of "0" in its ViewDidAppear, despite having 2+ rows produced with height. The project uses AutoLayout but the SubTableViewController's frame is set programmatically when added.

Any ideas what I can do to get something to appear here?

Structure of Data (periods are the subTable)

[{name:"activity 1",
  periods:[{name:"period1",desc:"desc1"},
           {name:"period2",desc:"desc2"},
           {name:"period3",desc:"desc3"}
          ]
 },
 {name:"activity 2",
  periods:[{name:"period1",desc:"desc1"},
           {name:"period2",desc:"desc2"},
           {name:"period3",desc:"desc3"}
          ]
 }]

ViewController

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [_data count];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];

    UIImageView *imageView = (UIImageView*)[cell viewWithTag:1];
    UIView *subTableView = (UIView*)[cell viewWithTag:3];

    return imageView.frame.size.height + subTableView.frame.size.height + 20;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier = @"tableViewCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    ActivityModel *model = _data[indexPath.row];

    UILabel *nameLabel = (UILabel*)[cell viewWithTag:2];
    nameLabel.text = model.name;

    UIView *internalView = (UIView*)[cell viewWithTag:10];

    SubTableViewController *subTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SubTableViewController"];
    subTableViewController.activityModel = model;
    subTableViewController.view.tag = 3;
    subTableViewController.view.frame = CGRectMake(0,
                                                   60,
                                         internalView.frame.size.width,                                        
                       subTableViewController.view.frame.size.height);
    [internalView addSubview:subTableViewController.view];
    [internalView bringSubviewToFront:subTableViewController.view];
    [subTableViewController.tableView reloadData];


    return cell;
}

SubTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

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


    int height = 0;
    for (int section = 0; section < [self numberOfSectionsInTableView:_tableView]; section++){
        for(int row = 0; row < [self tableView:_tableView numberOfRowsInSection:section]; row++){
            height += [self tableView:_tableView heightForRowAtIndexPath:[NSIndexPath indexPathForItem:row inSection:section]];
        }
    }

    CGRect tableFrame = self.tableView.frame;
    tableFrame.size.height = height;
    self.tableView.frame = tableFrame;

    CGRect viewFrame = self.view.frame;
    viewFrame.size.height = height;
    self.view.frame = viewFrame;
    [self.view bringSubviewToFront:_tableView];

    // [self.tableView layoutIfNeeded];
    // [self.tableView setNeedsDisplay];
    // [self.tableView reloadData];
    // _tableView.contentSize = CGSizeMake(600, 52);

    self.view.backgroundColor = [UIColor redColor];
    self.tableView.backgroundColor = [UIColor blueColor];

    self.tableView.hidden = NO;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [_activityModel.periods count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
    UITextView *textView = (UITextView*)[cell viewWithTag:5];

    float textViewHeight = [textView.text sizeWithFont:[UIFont systemFontOfSize:13] constrainedToSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 40, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;

    return nameLabel.frame.size.height + textViewHeight + 20;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableViewCell"];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    PeriodModel *model = _activityModel.periods[indexPath.row];

    UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
    UILabel *durationLabel = (UILabel*)[cell viewWithTag:4];
    UITextView *textView = (UITextView*)[cell viewWithTag:5];

    nameLabel.text = model.name;
    durationLabel.text = [NSString stringWithFormat:@"%d minutes", (int)(model.durationSeconds/60)];

    textView.text = model.description;

    textView.textContainerInset = UIEdgeInsetsZero;
    textView.textContainer.lineFragmentPadding = 0;
    textView.scrollEnabled = NO;

    CGRect frame = textView.frame;
    frame.size.height = [textView.text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(cell.contentView.frame.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;
    textView.frame = frame;

    return cell;
}

Simulator Image. The title is the outer UITableCell, and below it in red is the added SubTableViewController.view. The UITableView should cover the red, but is not appearing at all here. It is not hidden, underneath, etc.

在此处输入图片说明

Do not put a table view inside your cells.

There is little benefit to doing this for your described use. Use sections and rows. Each section would be your current cell. And each row in that section would be a row from your current embedded table view.

Further, if your internal table views had differing sizes you would be needing to calculate all of the internal cell heights for each external cell. That is exactly what happens with sections and rows, but you as the developer only need to worry about the rows and UITableView will handle the section sizing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM