Angel Jonathan Angel Jonathan - 4 months ago 64
iOS Question

Update text in section header (UICollectionReusableView)

How can I update

UICollectionView
section title? Headers (titles) for sections in my collection view show the total number of items available on each section and I need to update that title when the user has deleted items from the collection.

I'm implementing datasource method
collectionView:viewForSupplementaryElementOfKind:atIndexPath:
to set a custom header for each one of the sections in my collection view, as follows:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

UICollectionReusableView *view = nil;

if([kind isEqualToString:UICollectionElementKindSectionHeader]) {

view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"myCustomCollectionHeader" forIndexPath:indexPath];

MyCustomCollectionViewHeader *header = (MyCustomCollectionViewHeader *) view;

NSString *headerTitle;

if(indexPath.Section == 0) {
headerTitle = [NSString stringWithFormat:@"%lu items", (unsigned long) myArrayOfObjectsInFirstSection.count];
} else {
headerTitle = [NSString stringWithFormat:@"%lu items", (unsigned long) myArrayOfObjectsInSecondSection.count];
}

header.myLabelTitle.text = headerTitle;
}
return view;
}


My delete function is as follows:

- (void)deleteSelectedItems {

NSArray *indexPaths = self.collectionView.indexPathsForSelectedItems;

for(NSIndexPath *indexPath in indexPaths) {

NSString *numberOfItems;

if(indexPath.section == 0) {
[myArrayOfObjectsInFirstSection removeObjectAtIndex:indexPath.row];
numberOfItems = [NSString stringWithFormat:@"%lu items", (unsigned long)myArrayOfObjectsInFirstSection.count];
} else {
[myArrayOfObjectsInSecondSection removeObjectAtIndex:indexPath.row];
numberOfItems = [NSString stringWithFormat:@"%lu items", (unsigned long)myArrayOfObjectsInSecondSection.count];
}

[self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
}
/* after deleting all items, section title must be updated with the new value of numberOfItems*/
}


My app is able to set the number of items in collection view when the app starts, but after deleting items from collection view the header doesn't get updated.

Please advice

Answer

After many multiple attempts I came up with the following workaround:

Set a tag value for each section supplementary element... then later it's possible to search the object by tag:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    UICollectionReusableView *view = nil;

    if([kind isEqualToString:UICollectionElementKindSectionHeader]) {

        view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"myCustomCollectionHeader" forIndexPath:indexPath];

        MyCustomCollectionViewHeader *header = (MyCustomCollectionViewHeader *) view;

        if(indexPath.Section == 0) {
            header.tag = 100;
        } else {
            header.tag = 200;
        }

        // ...

    }
    return view;
}

- (void)updateSectionTitles {
    NSInteger numberOfItems;
    MyCollectionViewHeader *header;
    if(indexPath.section == 0) {
        header = (MyCollectionViewHeader *) [self.collectionView viewWithTag:100];
        numberOfItems = myArrayOfObjectsInFirstSection.count;
    } else {
        header = (MyCollectionViewHeader *) [self.collectionView viewWithTag:200];
        numberOfItems = myArrayOfObjectsInSecondSection.count;
    }
    header.myHeaderTitleLabel.text = [NSString stringWithFormat:@"There are %lu items", (unsigned long) numberOfItems];
    }
}

In my personal opinion I think it shouldn't be the way to go to update any section supplementary element in UICollectionView.

Another option is to call reload sections, but this reloads not only supplementary elements (headers, footers) but also the data of each section which may be a performance issue:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]];

Hope this may help anybody in the future or post with better approach :)

Comments