UITableView inside UICollectionViewCell

2019-08-13 15:16发布

问题:

I want to have UITableView inside my UICollectionViewCell. I would then dynamically change the content of UITableView through the subclass of UICollectionViewCell.

My subclass of UICollectionViewCell .h looks like this:

@interface ShopCollectionCell : UICollectionViewCell <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, weak) IBOutlet UILabel *myLabel;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end

in .m is just standard UITableView methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"bla"];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"bla"];
    }

    cell.textLabel.text = @"test";
    return cell;
}

in my UIViewController I have a UICollectionView where I do the following:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    ShopCollectionCell *cell = (ShopCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"shopDetailCell" forIndexPath:indexPath];

    if (cell == nil) {
        cell = [[ShopCollectionCell alloc] init];//:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    cell.myLabel.text = @"test";

    return cell;
}

I don't understand why I am getting zombie object ?!

回答1:

To be able to use dequeueReusableCellWithReuseIdentifier:forIndexPath you need to also register a class or a nib for that cell identifier.

in your viewDidLoad, you should use either of the two UITableView methods below to register a cell

registerNib:forCellReuseIdentifier:
registerClass:forCellReuseIdentifier:

Check out the UITableView docs for further details on how to use them

You should then be able to delete the following lines completely:

   if (cell == nil) {
        cell = [[ShopCollectionCell alloc] init];//:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

UPDATE: The error message you posted to me made it pretty easy to figure out what was wrong. You load the NIB with "self" as owner, but then you replace self with the first view loaded from the NIB. I would use a UIView as rootview in your NIB, and add that loaded view into the cell's contentView property.



回答2:

Try to remove alloc and init of collection view cell. dequeueReusableCellWithReuseIdentifier is must be enough. From apple documentation:

This method dequeues an existing cell if one is available or creates a new one based on the class or nib file you previously registered.



回答3:

Making following 3 changes worked for me.

  1. In ShopCollCell.xib, map tableView delegate and datasource to ShopCollectionCell class and not to File's owner.

  2. In ShopCollectionCell.m implement initWithCoder: method.

  3. In ShopCollectionCell.m implement awakeFromNib method and register UITableViewCell class for the mytableView here.

    - (id)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super initWithCoder:aDecoder]) {
    
        }
    
        return self;
    }
    
    
    - (void)awakeFromNib {
        [self.myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"bla"];
    }