UICollectionView: show the label "No item" in the section in which there is no item

I have a UICollectionView with 5 sections, some sections have data, and some sections (in my code this is section 2) do not (it depends on sever)
Therefore, I want to display a label ("No item") in a selection that does not contain data.

However, I can find any idea to do this, I hope someone can give me some suggestion or instruction to achieve it.
I would really appreciate any help.

Here is my code for intergrade sections

 -(UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ FriendsFanLevelHeaderView *headerView = (FriendsFanLevelHeaderView *)[self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"FanLevelHeader" forIndexPath:indexPath]; switch (indexPath.section) { case 0: [headerView.lblFanLevelTitle setText:@"Gold"]; break; case 1: [headerView.lblFanLevelTitle setText:@"Silver"]; break; case 2: [headerView.lblFanLevelTitle setText:@"Bronze"]; break; case 3: [headerView.lblFanLevelTitle setText:@"Green"]; break; case 4: [headerView.lblFanLevelTitle setText:@"Other"]; break; default: break; } return headerView; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ switch (section) { case 0: return 3; case 1: return 0; // it doesn't have any item case 2: return 2; case 3: return 3; case 4: return 5; default: return 0; } } - (FriendsCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ FriendsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"FriendsCollectionViewCell" forIndexPath:indexPath]; [cell.lblFriendBand setText:@"Band: White Mash "]; [cell.lblFriendGenre setText:@"Freestyle house, House, Freestyle music,"]; [cell.lblFriendECScore setText:@"EC score: 79"]; return cell; } 

enter image description here

==============================================

HERE I WANT

enter image description here

+5
source share
6 answers

You need to use UICollectionElementKindSectionFooter same way you use the section header. I am creating a simple CollectionView example to show what I mean:

enter image description here

So basically I create a universal footer and hide it when there is content to fill the cells:

Basic example:

 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section { NSArray *sectionContent = self.collectionViewData[section][COLLECTIONVIEW_CONTENT_KEY]; return ([sectionContent count] > 0) ? CGSizeMake(0, 0) : CGSizeMake(collectionView.frame.size.width, FOOTER_HEIGHT); } 

Where is my self.collectionViewData - NSArray of NSDictionary .

But in order to avoid gap restrictions, I highly recommend creating a separate xib for the footer and is applicable for both your collective viewing.

 -(UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ NSArray *sectionContent = self.collectionViewData[indexPath.section][COLLECTIONVIEW_CONTENT_KEY]; if([kind isEqualToString:UICollectionElementKindSectionHeader]) { UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath]; return headerView; } else { NSString *footerIdentifier = ([sectionContent count] > 0) ? @"blankFooter" : @"footer"; UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerIdentifier forIndexPath:indexPath]; return footerView; } } 

You can download a sample project here to view: https://bitbucket.org/Kettu/so_34526276

Bitbucket to this repository

+2
source

Suppose you have data (elements) for each section in an NSArray .

So you have an array of goldSectionItems , an array of silverSectionItems , an array of bronzeSectionItems , an array of greenSectionItems and an array of otherSectionItems .

What do you want to do:

  • when you have some items in the section that you want to display.
  • when you have no items in the section that you want to display "No item"

In case 1, you want to indicate in the form of a collection the number of elements that you have in your section using an array containing your elements.

In case 2, you want to indicate in the collection view that you have 1 element, which will be the "No Elements" cell.

 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { switch (section) { case 0: return MAX(1, goldSectionItems.count); case 1: // return at least 1 when you have no items from the server. // When you do not have any items in // you NSArray then you return 1, otherwise you return // the number of items in your array return MAX(1, silverSectionItems.count); case 2: return MAX(1, bronzeSectionItems.count); case 3: return MAX(1, greenSectionItems.count); case 4: return MAX(1, otherSectionItems.count); default: return 0; } } 

Note. MAX will return the maximum value between two operands. For example, if your silverSectionItems array silverSectionItems empty, the count property will return 0 , so MAX(1, 0) will return 1. If your silverSectionItems not empty, count will return N (where N>1 ), so MAX(1, N) will return N

Then in your -collectionView:cellForItemAtIndexPath: you want to check in which case you:

If you are in case 1, you want the cell to display normal content.

If you are in case 2, you want the cell to display “No item”.

 - (FriendsCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ FriendsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"FriendsCollectionViewCell" forIndexPath:indexPath]; // get the array that contains the items for your indexPath NSArray *items = [self itemArrayForIndexPath:indexPath]; // case 2 // if the section does not have any items then set up the // cell to display "No item" if (items.count == 0) { [cell.lblFriendBand setText:@"No item"]; [cell.lblFriendGenre setText:@""]; [cell.lblFriendECScore setText:@""]; } // case 1 // setup the cell with your items else { // get you item here and set up the cell with your content // Item *item = items[indexPath.item]; [cell.lblFriendBand setText:@"Band: White Mash "]; [cell.lblFriendGenre setText:@"Freestyle house, House, Freestyle music,"]; [cell.lblFriendECScore setText:@"EC score: 79"]; } return cell; } // return array for the corresponding indexPath - (NSArray *)itemArrayForIndexPath:(NSIndexPath *)indexPath { switch (indexPath.section) { case 0: return goldSectionItems; case 1: return silverSectionItems; case 2: return bronzeSectionItems; case 3: return greenSectionItems; case 4: return otherSectionItems; default: return nil; } } -(UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ FriendsFanLevelHeaderView *headerView = (FriendsFanLevelHeaderView *)[self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"FanLevelHeader" forIndexPath:indexPath]; switch (indexPath.section) { case 0: [headerView.lblFanLevelTitle setText:@"Gold"]; break; case 1: [headerView.lblFanLevelTitle setText:@"Silver"]; break; case 2: [headerView.lblFanLevelTitle setText:@"Bronze"]; break; case 3: [headerView.lblFanLevelTitle setText:@"Green"]; break; case 4: [headerView.lblFanLevelTitle setText:@"Other"]; break; default: break; } return headerView; } 

Feel that you don’t understand anything.

+2
source

I did this in one of my projects, but I use collectionView in each section of the collection, to scroll horizontally to each section, as shown below. you can get some idea

 if (row==0) { lblCoupons = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, collectionVCategory.frame.size.width, 50)]; // lblCoupons.tag = 99; [lblCoupons setText:@"No Coupons Found!"]; [lblCoupons setTextAlignment:NSTextAlignmentCenter]; [lblCoupons setFont:[UIFont systemFontOfSize:15]]; [collctnView.backgroundView layoutSubviews]; collctnView.backgroundView = lblCoupons; } else { [lblCoupons removeFromSuperview]; //[collectionVCategory.backgroundView removeAllSubviewsOfTag:99]; collctnView.backgroundView = nil; } 
+1
source

If you receive data in such a format that each index of the array itself contains one full array. Like recipeImages contains 3 objects, which themselves are arrays.

 NSArray *mainDishImages = [NSArray arrayWithObjects:@"egg_benedict.jpg", @"full_breakfast.jpg", @"ham_and_cheese_panini.jpg", @"ham_and_egg_sandwich.jpg", nil]; NSArray *drinkDessertImages = [NSArray arrayWithObjects:@"green_tea.jpg", @"starbucks_coffee.jpg", @"white_chocolate_donut.jpg", nil]; NSArray *sideDishes = [NSArray arrayWithObjects:@"green_tea.jpg", @"starbucks_coffee.jpg", @"white_chocolate_donut.jpg", nil]; recipeImages = [NSArray arrayWithObjects:mainDishImages, drinkDessertImages, sideDishes ,nil]; 

You can specify the number of sections in the collection view as:

 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return [recipeImages count]; } 

and the number of rows in each section as

 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return [[recipeImages objectAtIndex:section] count]; } 

If your data is in this format, you can check if there is any data in the specified section by receiving an array in the specific section.

 -(UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ NSArray *temp_arr_gold = [recipeImages objectAtIndex:0]; NSArray *temp_arr_silver = [recipeImages objectAtIndex:1]; NSArray *temp_arr_bronze = [recipeImages objectAtIndex:2]; NSArray *temp_arr_green = [recipeImages objectAtIndex:3]; NSArray *temp_arr_other = [recipeImages objectAtIndex:4]; FriendsFanLevelHeaderView *headerView = (FriendsFanLevelHeaderView *)[self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"FanLevelHeader" forIndexPath:indexPath]; switch (indexPath.section) { case 0: if (temp_arr_gold.count !=0) { [headerView.lblFanLevelTitle setText:@"Gold"]; } else { [headerView.lblFanLevelTitle setText:@"No item"]; } break; case 1: if (temp_arr_silver.count !=0) { [headerView.lblFanLevelTitle setText:@"Silver"]; } else { [headerView.lblFanLevelTitle setText:@"No item"]; } break; case 2: if (temp_arr_bronze.count !=0) { [headerView.lblFanLevelTitle setText:@"Bronze"]; } else { [headerView.lblFanLevelTitle setText:@"No item"]; } break; case 3: if (temp_arr_green.count !=0) { [headerView.lblFanLevelTitle setText:@"Green"]; } else { [headerView.lblFanLevelTitle setText:@"No item"]; } break; case 4: if (temp_arr_other.count !=0) { [headerView.lblFanLevelTitle setText:@"Other"]; } else { [headerView.lblFanLevelTitle setText:@"No item"]; } break; default: break; } return headerView; 

}

Hope this helps ... Happy coding.

+1
source

One way could be to create another “No Item” cell in the View collection.

Then in collectionView:numberOfItemsInSection: always return at least 1 to place the No Item cell.

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { // TODO: check dataSource array for "NO FRIENDS" // TODO: If true // NoFriendsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"NoFriendsCollectionViewCell" forIndexPath:indexPath]; // cell.label.text = "No Item"; // return cell; // else FriendsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"FriendsCollectionViewCell" forIndexPath:indexPath]; [cell.lblFriendBand setText:@"Band: White Mash "]; [cell.lblFriendGenre setText:@"Freestyle house, House, Freestyle music,"]; [cell.lblFriendECScore setText:@"EC score: 79"]; return cell; } 
+1
source

if you want to show the “no item” label, you need to return 1 to numberOfItemsInSection, and then when the collection request asks for a cell, it depends on the actual quantity of your item, you can return either “no item” or the actual first item in your collection when The line number of the index path is 1.

+1
source

Source: https://habr.com/ru/post/1239474/


All Articles