in one of my application i have implemented dashboard screen with collection view and when user clicks on collection view cell's it is not interacting this is happening to only iPhone12 pro max users
currently i don't have that real time device to test but i have tested in iPhone12 pro max simulator and its working fine
can you please suggest what was the cause or any suggestions?
thanks in advance
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
customClassCollectionViewCellOne *cell = [[customClassCollectionViewCellOne alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
cell = (customClassCollectionViewCellOne *)[collectionView dequeueReusableCellWithReuseIdentifier:#"accountBalance_main_collectionview" forIndexPath:indexPath];
cell.balanceArray = newbalanceArray;
cell.delegate = self;
[cell.collectionView reloadData];
return cell;
}
else if (indexPath.section == 1)
{
customClassCollectionViewCellTwo *cell = [[customClassCollectionViewCellTwo alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
cell = (customClassCollectionViewCellTwo *)[collectionView dequeueReusableCellWithReuseIdentifier:#"QuickActions_main_collectionview" forIndexPath:indexPath];
cell.quickActionList = viewModel.quickActionsList;
cell.delegate = self;
[cell.collectionView reloadData];
return cell;
}
else
{
customClassCollectionViewCellThree *cell = [[customClassCollectionViewCellThree alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
cell = (customClassCollectionViewCellThree *)[collectionView dequeueReusableCellWithReuseIdentifier:#"GetInTouch_main_collectionview" forIndexPath:indexPath];
cell.getinTouchList = viewModel.touchList;
cell.delegate = self;
[cell.collectionView reloadData];
return cell;
}
}
just informing
custom collectionview cell class contains sub collection view again
Try adding your view components to the cell's content view and not directly as a subview.
Related
I want to display two collection view using segment controller, on change of segment second collection view will display.
my code is :
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"morningcell" forIndexPath:indexPath];
UICollectionViewCell *cell1 = [collectionView dequeueReusableCellWithReuseIdentifier:#"eveningcell" forIndexPath:indexPath];
if (_segment.selectedSegmentIndex == 0) {
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.frame.size.height,cell.frame.size.width)];
lbl.text = [numbers objectAtIndex:indexPath.row];
[cell addSubview:lbl];
[lbl setTextAlignment:UITextAlignmentCenter];
return cell;
}
else{
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell1.frame.size.height,cell1.frame.size.width)];
lbl.text = [numbers objectAtIndex:indexPath.row];
[cell1 addSubview:lbl];
[lbl setTextAlignment:UITextAlignmentCenter];
return cell1;
}}
Do not create two collectionView for the task that you want because you can achieve it using a single collectionView.
#interface YourVC(), UICollectionViewDelegate, UICollectionViewDataSource {
NSArray *arrayOfModelsForFirstCollectionView;
NSArray *arrayOfModelsForSecondCollectionView;
}
#end
#implementation YourVC
-(void)viewDidLoad{
[super viewDidLoad];
//Fetch Data For both Segments Using Your Web API Call or Local Database API Call
}
-(IBAction)didChangeSegmentIndex:(id)sender{
//When segment is changed you need to tell your collectionView to update the data.
[self.collectionView reloadData];
}
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfRowsInSection:(NSInteger)section{
//When reloadData is call this method will check that which index is selected.
//And according to selection it will create number of cells.
if (self.segmentControl.selectedIndex == 0){
return arrayOfModelsForFirstCollectionView.count;
}else{
return arrayOfModelsForSecondCollectionView.count;
}
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
//While creating a cell it will check which segment is selected so it will initialize and create the cell with respect to selection of segments.
//Hence you have created two different cells in a single collectionView toggling with a segmentControl.
if (_segment.selectedSegmentIndex == 0) {
return [self makeCellForFirstSegmentAtIndexPath: indexPath];
}
else{
return [self makeCellForSecondSegmentAtIndexPath: indexPath];
}
}
-(UITableViewCell *)makeCellForFirstSegmentAtIndexPath:(NSIndexPath *)indexPath{
//To show data from array you need to use arrayOfModelsForFirstCollectionView because this array is associated with First Segment Index
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"morningcell" forIndexPath:indexPath];
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.frame.size.height,cell.frame.size.width)];
lbl.text = [arrayOfModelsForFirstCollectionView objectAtIndex:indexPath.row];
[cell addSubview:lbl];
[lbl setTextAlignment:UITextAlignmentCenter];
return cell;
}
-(UITableViewCell *)makeCellForSecondSegmentAtIndexPath:(NSIndexPath *)indexPath{
//To show data from array you need to use arrayOfModelsForSecondCollectionView because this array is associated with Second Segment Index
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"eveningcell" forIndexPath:indexPath];
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.frame.size.height,cell.frame.size.width)];
lbl.text = [arrayOfModelsForSecondCollectionView objectAtIndex:indexPath.row];
[cell addSubview:lbl];
[lbl setTextAlignment:UITextAlignmentCenter];
return cell;
}
#end
I have two different custom cell in my tableview, In the first cell I add a custom cell line under the system cell line:
_bottom_line = [[UIView alloc] initWithFrame:CGRectMake(0, 49, kScreen_Width, 1)];
_bottom_line.backgroundColor = Back_Color_QQ;
[part3 addSubview:_bottom_line];
In the controller to setup my custom cell;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) { // my first cell
static NSString *id_cell1 = #"cell1";
AgDetailTechCell *cell = [tableView dequeueReusableCellWithIdentifier:id_cell1];
if (cell == nil) {
cell = [[AgDetailTechCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id_cell1];
}
((AgDetailTechCell *)cell).model = self.headerModel;
((AgDetailTechCell *)cell).indexPath = indexPath;
((AgDetailTechCell *)cell).delegate = self;
_head_cell = cell;
_head_cell.comemntCountlabel.text = self.headerModel.lml_commentTimes;
_head_cell.likeCountlabel.text = self.headerModel.lml_likeTimes;
return cell;
}else { // other cells
static NSString *id_cell2 = #"cell2";
AgPreOrHelpCommentCell *cell = [tableView dequeueReusableCellWithIdentifier:id_cell2];
if (cell == nil) {
//cell = [[AgPreOrHelpCommentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id_cell2];
cell = [[NSBundle mainBundle] loadNibNamed:#"AgPreOrHelpCommentCell" owner:self options:nil].firstObject;
}
cell.delegate = self;
cell.indexPath = indexPath;
[cell initCellDataWithModel:self.dataSource[indexPath.row]];
cell.refresh = ^(UITableViewCell *currentCell) {
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
};
return cell;
}
}
The first time into the controller, it shows well. But after I scroll my tableview to hide and show again, my custom bottom line dismiss, I cannot find it.And I refresh my tableView, the custom line appears again. I have token 2 pictures to explain more detail:
UPDATE
Use Harsh's suggestion, but no change for the issue:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell.reuseIdentifier isEqualToString:#"cell1"]) {
// customs bottom_line
UIView * bottom_line = [[UIView alloc] initWithFrame:CGRectMake(0, 49, kScreen_Width, 1)];
bottom_line.backgroundColor = Back_Color_QQ;
[((AgDetailTechCell *)cell).part3 addSubview:bottom_line];
}
}
If your soul purpose is to extend the default separators from end to end.
Check this post How to fix UITableView separator on iOS 7?
Maybe your bottom line is out of your cell. Make sure you return 50 or greater height for cells. Another thing is disable the system bottom line of UITableView.
Hi i'm trying to customize my collectionviewcell depending on its indexPath but also if I set
if (indexPath.row == 0)
{
[cell addSubView: view];
}
the view appear random in some cells.
This is the code I'm using
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSInteger row = indexPath.row;
UIView *contentCell = [[UIView alloc] initWithFrame:cell.frame];
if (row == 0)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(1.0f, 1.0f, 50.0f, 50.0f)];
label.text = #"Test";
[contentCell addSubview:label];
}
[cell addSubview:contentCell];
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"container"]];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%d", indexPath.row);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(414, 228);
}
You have to read about reusable cells.
you can avoid the problem for now by doing this.
if (row == 0)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(1.0f, 1.0f, 50.0f, 50.0f)];
label.text = #"Test";
label.tag = 200;
[contentCell addSubview:label];
}else{
UIView* lbl = [contentCell viewWithTag:200];
if(lbl)
[lbl removeFromSuperView];
}
but this will affect the scrolling and memory performance, you can put the label in the cell by default && show/hide it in the if/else blocks
You are adding view several times as a subview. Cells are reused due to "dequeueReusableCellWithReuseIdentifier", so after you scroll up and down, you get back existing view, which already has subview added.
You should read more about reusing cells.
One way to avoid that behavior is to create all views when you create a cell and just show / hide them.
Otherwise create cells with different identifier for different rows - in your case for row 0.
This is a very strange problem. I have a UICollectionView which seems to run perfectly on the iPad or the simulator as an iPad, but has a problem when running on the iPhone or iPhone simulator. The problem is that if an item is added to the datasource and I perform a reloadData, the freshly added item will not show up in the collection view. If I exit the view controller altogether and reopen it, the item is there. This problem is on the iPhone only, not the iPad, which works perfectly.
In all cases, the number of items returned is correct and the number of passes through the dequeue loop is correct (verified via debugger).
Relevant code below. I initialize the CV in viewDidAppear with the following:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.minimumInteritemSpacing = 3.0f;
UICollectionViewCell *cvCell = [[UICollectionViewCell alloc] init];
cv = [[UICollectionView alloc] initWithFrame:CGRectMake(1.0f, 80.0f, [Utility screenWidth]-2.0f, [Utility screenHeight]-60.0f) collectionViewLayout:flowLayout];
[cv setDelegate:self];
[cv setDataSource:self];
[cv setAllowsMultipleSelection:NO];
[cv setAllowsSelection:NO];
[cv setBackgroundColor: [UIColor whiteColor]];
[cv registerClass:[cvCell class] forCellWithReuseIdentifier:#"Cell"];
[self.view addSubview:cv];
[self.view sendSubviewToBack:cv];
[self queryData]; // [self queryData] also does a [cv reloadData]
The CV delegate is as follows:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection: (NSInteger)section
{
return [cvData count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
[cell.contentView.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
Item *item = (Item *) [cvData objectAtIndex:indexPath.row];
CGFloat cellSize = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) ? 100.0f : 160.0f;
ImageWithAttachedLabel *imageWithLabel = [[ImageWithAttachedLabel alloc] initWithFrame:CGRectMake(0,0,cellSize,cellSize)
withImage: [UIImage imageWithData: item.itemPhoto]
withLabel: item.itemName
roundBottoms: YES];
[cell.contentView addSubview:imageWithLabel];
return cell;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 3.0f;
}
Running the debugger finds that numberOfItemsInSection is returns the CORRECT count of the items and the number of passes through the dequeue loop is correct, but the last item added (which should always be the last cell in the cv, as the items are unsorted) is not displayed.
I haven't been able to find any articles mentioning anything quite like this so I'm guessing I have a bug somewhere, but it is elusive.
Any suggestions appreciated.
Perhaps you can force the newly added item to be displayed by doing this after you add the new item to your data source:
int size = [cvData count];
NSIndexPath *lastCell = [NSIndexPath indexPathForRow:size inSection:0];
[self.collectionView insertItemsAtIndexPaths:#[lastCell]];
(assuming you point self.collectionView at your cv)
I'm very new to UICollectionViews. I'm making a universal app. What I want is that on the iPad there are 2 cells on each row. But on the iPhone there is only one cell on each row. I was able to get the iPad version set correctly. But I can't get my head around the iPhone settings.
Here are the settings so far. And has you can see on my storyboard it looks oké. But when I run it I see that there are still two cells on each row.
Can someone help me with this ?
Kind regards
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[CVCell class] forCellWithReuseIdentifier:#"cvCell"];
// Configure layout
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(100, 100)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.collectionView setCollectionViewLayout:flowLayout];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
deviceModel = (NSString*)[UIDevice currentDevice].model;
NSLog(#"device is = %#",deviceModel);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if ([deviceModel isEqualToString:#"iPhone Simulator"]) {
return 1;
}else
{
return 2;
}
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 3;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// Setup cell identifier
static NSString *cellIdentifier = #"cvCell";
/* Uncomment this block to use subclass-based cells */
CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
if (indexPath.section == 0) {
cell.backgroundColor = [UIColor redColor];
}
if (indexPath.section == 1) {
cell.backgroundColor = [UIColor blueColor];
}
cell.titleLabel.text = [NSString stringWithFormat:#"item %ld",(long)indexPath.section];
// Return the cell
return cell;
}
Check this code which will give you one item in iPhone cell and two item in iPad..