Facing an issue with the scrolling of CollectionView. When user drags the scroll and leaves it the collectionView scroll jerks just before stopping. The jerk/flicker is very less but I am not able to understand why it is not as smooth as collection view usually is.
I am just using these methods to load CollectionView:
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 500;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
EmojiCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:EmojiCellIdentifier forIndexPath:indexPath];
return cell;
}
Below is the link of the code: CODE
Related
I am trying to make an app with CollectionView, but I'm facing a problem. As you can see from my code, I received the callback in both numberofSectionsINCollectionView and numberOfItemsInsection, but cannot receive the callback in cellForItemAtIndexPath, which makes the cell not show up inside CollectionView. However, with another computer with the same Xcode version and connected to the same iPhone (6 Plus), I can receive the callback in cellForItemAtIndexPath.
I don't know why. Could you please tell me how to fix the problem? I think it's attributed to the setting in Xcode, but I'm not sure.
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if (self.useSection) {
return self.dataSource.count;
}
return 1;}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.useSection)
return [[self.dataSource objectAtIndex:section] count];
return self.dataSource.count; }
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:[self reuseIdentifierForIndexPath:indexPath] forIndexPath:indexPath];
return cell;
}
I double-checked if delegate is set like
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
cellForItemAtIndexPath won't be called if your cell size is (0,0) or count is 0 maybe you can try add this code :
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:
(NSIndexPath *)indexPath{ return CGSizeMake(100,100);}
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
All,
I am adding a UICollectionView to a UIView but it's failing to load cells because it seems that this:
[self.buttonsCollectionView registerNib:[UINib nibWithNibName:#"AccountMenuCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"AccountMenuCell"];
Is getting loaded after it hits the delegates for the UICollectionView. Normally this would be placed in viewDidLoad but is not available in a UIView.
- (AccountMenuCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AccountMenuCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AccountMenuCell" forIndexPath:indexPath];
[cell.accountMenuButton setTitle:#"Deposit" forState:UIControlStateNormal];
return cell;
}
Any guidance?
EDIT:
So I am using a view from the storyboard initially and then adding a subview which is Account Menu. Within this view I have a Collection View.
Try to use with the default method and instantiate your Cell inside of the cellForItem...
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AccountMenuCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AccountMenuCell" forIndexPath:indexPath];
[cell.accountMenuButton setTitle:#"Deposit" forState:UIControlStateNormal];
return cell;
}
and .. verify with Breakpoints if your code is running..
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:
UICollectionView refreshes data after scrolling and changes the position of the cells. How can I stop it? I don't want to call cellForItemAtIndexPath on every scrolling?
I don't have too much data.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.logo.image=[UIImage imageNamed:[NSString stringWithFormat:#"%#.jpg",news[indexPath.row]]];
return cell;
}