1

I have a UICollectionView inside a UITableViewCell. You may refer the image at here

I would like to reload the collectionView if any update happen.

I have done some research and found this :

  1. how to reload a collectionview that is inside a tableviewcell
  2. Reloading collection view inside a table view cell happens after all cells in table view have been loaded
  3. UICollectionView not updating inside UITableViewCell

I called the @IBOutlet weak var collectionView: UICollectionView! from UITableViewCell to UITableViewController at cellForRowAt.

Here is the code:

var refreshNow: Bool = false

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Storyboard.allCardCell, for: indexPath) as! AllCardTableViewCell

        if refreshNow {
          cell.collectionView.reloadData()
          refreshNow = false
        }

        cell.collectionView.collectionViewLayout.invalidateLayout()
        return cell
    }

If the user click Ok on UIAlertAction :

let alert = UIAlertController(title: "Success", message: "Card successfully added", preferredStyle: .alert)
                let action = UIAlertAction(title: "Ok", style: .default) { (action) in
                    self.refreshNow = true
                    self.tableView.reloadData()
                }
                alert.addAction(action)
                self.present(alert, animated: true, completion: nil)

The reason why I put the refreshNow is to prevent the apps from lagging and slow. But still did not update if any changes happen.

The problem is the collectionView did not refresh. But when I debug, it was went through the cell.collectionView.reloadData().

The update/changes only happen when I restart the apps. I want it to be so called real-times update.

Any help is really appreciated and many thanks.

Image credit: How to use StoryBoard quick build a collectionView inside UITableViewCell

Sariyanti
  • 37
  • 1
  • 5

4 Answers4

1

At end of your update add:

DispatchQueue.main.async() { () -> Void in
   self.tableView.reloadData()
}
oscar castellon
  • 3,048
  • 30
  • 19
0

In your case, you should assign tag to your collection view in order to get access outside the cellForRowAt function.

This is how your function should look like:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: Storyboard.allCardCell, for: indexPath) as! AllCardTableViewCell

    cell.collectionView.tag = 1234
    return cell
}

and the action will reload it will access the collectionView by using the tag

let action = UIAlertAction(title: "Ok", style: .default) { (action) in
    let collectionView = self.tableView.viewWithTag(1234) as! UICollectionView
    collectionView.reloadData()
}

Also take note that cellForRowAt will keep reload the content based what you added inside it every time the cell appear. So, keep updating your data outside the cellForRowAt function.

xmhafiz
  • 3,482
  • 1
  • 18
  • 26
  • I have table view controller that one of the cells has collection view this code will crash at let collectionView = self.tableView.viewWithTag(1234) as! UICollectionView – Saeed Rahmatolahi Dec 20 '17 at 08:29
0

Because you reused UITableViewCell so you must alway reload your UICollectionView. If you use refreshNow to reload UICollectionView, at the cell have refreshNow = false, UICollectionView will display like cell that it 's reused => wrong enter image description here

Udate rep:

See , in picture uitableviewcell 1 will reuse at index 6. If you not reload content of cell (reload collectionview) it will display like uitableviewcell 1 at index 0

Nguyen Hoan
  • 1,583
  • 1
  • 11
  • 18
-1
    #import "AddPhotoViewController.h"
    #import "PhotoTableViewCell.h"
    #import "ShareTableViewCell.h"

    @interface AddPhotoViewController ()

    @property (weak, nonatomic) IBOutlet UITableView *tblView;

    @property (strong,nonatomic)NSMutableArray *arrImages,*arrIndexPath,*selectImages;

    @end

    #pragma mark - TableViewDelegate&DataSource

      - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 3;

    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

        UITableViewCell *returnCell;

        static NSString *cellIdentifier = @"CellOne";
        static NSString *cellIdentifierTwo = @"CellTwo";
        static NSString *cellIdentifierThree = @"CellThree";
        if (indexPath.row == 0) {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            returnCell = cell;
        } else if (indexPath.row == 1){
            ShareTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierTwo forIndexPath:indexPath];
            cell.viewMood.layer.cornerRadius = 5;
            cell.viewPeople.layer.cornerRadius = 5;
            [cell.viewMood layer].borderWidth = 1;
            [cell.viewMood layer].borderColor = [UIColor colorWithRed:241.0/255.0 green:143.0/255.0 blue:48.0/255.0 alpha:1].CGColor;
            [cell.viewPeople layer].borderWidth = 1;
            [cell.viewPeople layer].borderColor = [UIColor colorWithRed:241.0/255.0 green:143.0/255.0 blue:48.0/255.0 alpha:1].CGColor;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            returnCell = cell;
        }else if (indexPath.row == 2){
            PhotoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierThree forIndexPath:indexPath];
            cell.collView.dataSource = self;
            cell.collView.delegate = self;

            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            returnCell = cell;
        }

        return  returnCell;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

        return UITableViewAutomaticDimension;

    }

     #pragma mark-   UIImagePickerControllerDelegate

      -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

        UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
        [_arrImages addObject:chosenImage];

        PhotoTableViewCell *cell = [self.tblView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];

        [cell.collView reloadData];

        [picker dismissViewControllerAnimated:YES completion:^{

        }];
    }

#pragma mark - CollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [_arrImages count];
}

- ( UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *cellIdentifier = @"CellCollection";
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    UIImageView *imgView = [(UIImageView*)[cell contentView] viewWithTag:100];
    UIImageView *imgViewTick = [(UIImageView*)[cell contentView] viewWithTag:200];
    UIView *view = [(UIView*)[cell contentView] viewWithTag:300];
    if (indexPath.row == 0){
        imgViewTick.hidden = YES;
        view.hidden = YES;
    }

    if  ([_arrIndexPath containsObject:indexPath]) {

        [_selectImages removeAllObjects];

        view.hidden = NO;
        view.alpha = 0.4;
        imgViewTick.hidden = NO;
        imgView.image = [_arrImages objectAtIndex:indexPath.row];
        [_selectImages addObject:[_arrImages objectAtIndex:indexPath.row]];
        NSLog(@"Pick images:%@",_selectImages);

    }else{
        view.hidden = YES;
        imgViewTick.hidden = YES;

        imgView.image = [_arrImages objectAtIndex:indexPath.row];
    }

    return  cell;
}