I am using custom UICollectionView layout for having different size of cells and I am not able to have a section in this.
Is it good idea to use multiple UICollectionViews in the same UIViewController? Any suggestion please?
it's simple
for every UICollectionView Delegates
- (NSUInteger)maximumNumberOfColumnsForCollectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout
- (CGFloat)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout
heightForItemAtIndexPath:(NSIndexPath*)indexPath
- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
cellForItemAtIndexPath:(NSIndexPath*)indexPath
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section`
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView`
write condition inside:
if (collectionView == myCollectionView1)
{
// do this
}
else if (collectionView == myCollectionView2)
{
// do this
}
lets say for example in
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section
{
if (collectionView == myCollectionView1)
{
return 12;
}
else if (collectionView == myCollectionView2)
{
return 7;
}
return 0;
}
Use Tag Property for distinguish between multiple UICollectionView or UITableView in one View Controller.
firstCollectionView.tag = 1;
secondCollectionView.tag = 2;
and so on ...
Now, In delegate methods use if to check UICollectionView
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if(collectionView.tag == 1)
{
//cell for first UICollectionView or CollectionView with tag equal to 1
}
else if(collection.tag == 2)
{
//cell for second UICollectionView or CollectionView with tag equal to 2
}
}
Use same technique in other delegate methods.
Related
I've a strange behavior with UICollectionView.
In Figure 1 is shown the correct behavior when the user scroll up the collection: the items goes under header view.
[FIGURE 1]
When I reload Items after a search, some items goes over header during scroll.
I've no idea about the cause...
Any ideas or suggestions?
Thanks.
EDIT
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetWidth([UIScreen mainScreen].bounds) * 0.612f);
}
What worked for me is to call reloadData() instead of trying to reload with animation (reloadSections()).
In my case, I had a show/hide button to toggle the number of rows in section between item count and 0 (expand the content of the section).
When I replaced
collectionView?.reloadSections([section])
with
collectionView?.reloadData()
I no longer had the issue.
My working code for UICollectionView along with HeaderView inside UIViewController:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(100, 100);
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"header" forIndexPath:indexPath];
return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 100);
}
Storyboard:
Output:
Please check this. Hope this will help you in some other way.
You can try to set sectionHeadersPinToVisibleBounds = true property on your UICollectionViewFlowLayout. Because every UICollectionView has own layout.
Apple doc
A Boolean value indicating whether headers pin to the top of the collection view bounds during scrolling.
Maybe it will help. Add this code into viewDidLoad.
(self.yourCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).sectionHeadersPinToVisibleBounds = true
After trying many solutions in my case that works,
collectionView.clipsToBounds = true
I would like to have a UICollectionView that, in the first row there is a cell with all the row's width, and the second row has 3 cells.
I have researched the documentation but I'm not able to do it. Something like this:
Thanks in advance
Make 2 Cell prototypes in collection view in your storyboard, and set them reuse identifiers
In your ViewController's .m file implement this functions
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 6;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
if (/*condition for small cell*/)// e.g. indexPath.row % 3 != 0
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"smallCell" forIndexPath:indexPath];
else
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"bigCell" forIndexPath:indexPath];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (/*condition for small cell*/) // e.g. indexPath.row % 3 != 0
return CGSizeMake(65, 50);
return CGSizeMake(318, 50);
}
After doing this you will have something like this:
I have two collectionViews in one controller, cellForItemAtIndexPath works fine with the below code
if(collectionView == collectionview1){
}
else
{}
But it does not work for the below method
(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
}
use different tags, say 1 and 2 for the two collectionviews.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if(collectionView.tag == 1){
//do stuffs related to the first collectionView
}else{
//do stuffs related to the first collectionView
}
}
I am having problem with my iOS app which I am not sure what is the root cause of it even after I've turned on NSZombie to debug.
Already tried to google with reliable source but still couldn't get any answer.
For my iOS App, I am using MMDrawerController Library as the left slide menu. Which I am having a problem when I switching view from left menu, if the page contains UICollectionView, it will crash with the message below.
[UICollectionView performSelector:withObject:]: message sent to deallocated instance
The view load smooth for the first time, but when I attempt to switch back from another view, it crashed with the error above.
Here are my UICollectionView Data Source and cell builder functions
#pragma mark: UICollectionViewCell Builder
- (ItemNormalCVCell *)buildItemNormalCVCell:(NSIndexPath *)indexPath
{
ItemNormalCVCell *cell = [self.mCollectionView dequeueReusableCellWithReuseIdentifier:#"CVCellItemNormal" forIndexPath:indexPath];
return cell;
}
- (LoadingCVCell *)buildLoadingCVCell:(NSIndexPath *)indexPath
{
LoadingCVCell *cell = [self.mCollectionView dequeueReusableCellWithReuseIdentifier:#"CVCellLoading" forIndexPath:indexPath];
return cell;
}
#pragma mark: UICollectionView DataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSInteger itemsCount = self.items.count;
if( self.isLoading_.boolValue )
return itemsCount + 1;
return itemsCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger itemsCount = self.items.count;
if( self.isLoading_.boolValue ){
if( indexPath.row == itemsCount )
return [self buildLoadingCVCell:indexPath];
}
return [self buildItemNormalCVCell:indexPath];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat cvWidth = (self.view.frame.size.width / 2) - 1.f;
return CGSizeMake(cvWidth, 300.f);
}
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0, 0, 0, 1.f); // top, left, bottom, right
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 1.f;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 1.f;
}
I would like to have a UICollectionView that, in the first row there is a cell with all the row's width, and the second row has 3 cells.
I have researched the documentation but I'm not able to do it. Something like this:
Thanks in advance
Make 2 Cell prototypes in collection view in your storyboard, and set them reuse identifiers
In your ViewController's .m file implement this functions
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 6;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
if (/*condition for small cell*/)// e.g. indexPath.row % 3 != 0
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"smallCell" forIndexPath:indexPath];
else
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"bigCell" forIndexPath:indexPath];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (/*condition for small cell*/) // e.g. indexPath.row % 3 != 0
return CGSizeMake(65, 50);
return CGSizeMake(318, 50);
}
After doing this you will have something like this: