I've been working my apps to run on iOS 8 and trying to consume data from the restful API. After getting response from the webservice I'm trying to reload the collectionview from the delegate method.I get the valid numeric count as 5 from my array for numberOfItemsInSection but cellForItemAtIndexPath not getting called.
I see in one scenario, If I hardcode the numberOfItemsInSection return count as 5 then cellForItemAtIndexPath is perfectly called while reload.
Here is my code snippet:
#pragma mark = UICollectionViewDataSource
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [offerModel.arrayOffers count];
}
- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
cellForItemAtIndexPath:(NSIndexPath*)indexPath {
NSString *identifier = #"OfferCell";
static BOOL nibMyCellloaded = NO;
if(!nibMyCellloaded){
UINib *nib = [UINib nibWithNibName:identifier bundle: nil];
[offerCollectionView registerNib:nib forCellWithReuseIdentifier:identifier];
nibMyCellloaded = YES;
}
OfferCell* cell = (OfferCell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier
forIndexPath:indexPath]; // // Commented binding values return
cell;
}
- (void)updateOfferList{
[offerCollectionView reloadData];
}
-(void)viewDidLoad{
[offerCollectionView registerClass:[OfferCell class] forCellWithReuseIdentifier:#"OfferCell"];
// set up delegates
self.offerCollectionView.delegate = self;
self.offerCollectionView.dataSource = self;
}
Please help me on this. Quick replies are most appreciated. Thanks
Finally I found an answer for my blocker. I just Reloading some items didn't work for me using reload data. Since CV default flow layout does some internal operation itself to reload data when we forced, In my case, I'm using customviewlayout here layoutAttributesForItemAtIndexPath and layoutAttributesForElementsInRect called only when the section gets loaded. Here it works because the collectionView has just one section, I've reloaded specific section would make contents correctly reloaded in the CV.
At my API handler delegate method placed the below code snippet,
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
[self.collectionView reloadData];
Thanks.
Related
I want to call didSelectItemAtIndexPath: for particular index path but I can't call it programmatically in cellForItemAtIndexPath because collection is not yet ready, I will get cell as nil. Do we have any delegate method or any other UIView method that is called after collection view is ready?
I have tried willDisplayCell: but it is not made for relevant work, couldn't find anything else.
I want to call didSelectItemAtIndexPath:
Don't. This is a delegate method. It is called by the runtime when the user selects an item. You must never call this yourself.
You have to do it programmatically utilising your manual logics. :)
The underlying concept is that get the indexes of selected cells and reload those specific cells only.
Declare a global var
NSMutableArray array_indexpath;
in your did select method add indexes of selected cells.
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
array_indexpath=[[NSMutableArray alloc]init];
[array_indexpath addObject:indexPath];
[self.myCollectionView reloadItemsAtIndexPaths:array_indexpath];
}
and in your cell for cellForItemAtIndexPath method check the indexes and reload it as required.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ShubhCalendarCollectionViewCell *cell =[collectionView dequeueReusableCellWithReuseIdentifier:#"ShubhCalendarCollectionViewCell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
if (array_indexpath.count !=0)
{
for (int i=0; i<[array_indexpath count]; i++)
{
if ([array_indexpath objectAtIndex:i] == indexPath)
{
cell.backgroundColor=[UIColor greenColor];
}
}
}
return cell;
}
Hope it helps.. Happy Coding.. :)
I just want to create a UICollectionView as a linear list. That is if the user enters a 4 values in 4 repeats of the textfield, The text has to store in the MutableArray (Which determines the number of collection items).
The problem what I am facing is,
When the view appears, the collectionview starts loading. Initially, data is 0. So, after completion of inserting object in the array. The change should reflect in the Collectionview too. So, after reloading the collectionview, the first item is shown. But, from the next repeats, The data which is recently, entered in the array is inherited to all the cells. Please, help me what to do.
howmanypeople=[routescore.text intValue];
[self.collectionView reloadData]; // Reloading the view
This code is for item at indexPath :-
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = #"cvCell2";
static BOOL nibMyCellloaded = NO;
if(!nibMyCellloaded)
{
UINib *nib = [UINib nibWithNibName:#"CustomCollectionViewCell" bundle: nil];
[collectionView registerNib:nib forCellWithReuseIdentifier:identifier];
nibMyCellloaded = YES;
}
cell = (CustomCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cvCell2" forIndexPath:indexPath];
cell.cellimage.image=[UIImage imageNamed:#"ic_lomobile_transit_scooter_small.png"];
cell.cellabel.text=route;
cell.backgroundColor=[UIColor lightGrayColor]
return cell;
}
I have a UITableView with a cell that has two labels in it. The table view is linked to the dataSource and delegate, the labels in the cell are linked to an IBOutlet, what not. It looks to me like this should work, but this code below is not running so the Cell or labels are not populated with text. Any ideas? Or anything I'm missing?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"theLabelCell";
CustomClassCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
CustomClassText *customText = _arrayThatHasText[indexPath.row];
if (![self isSelectionMode]) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.TitleLabel.text = customText.firstLabel;
cell.TextLabel.text = customText.secondLabel;
return cell;
}
Did you remember to also register the cell identifier for reuse?
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomClassCell" bundle:nil] forCellReuseIdentifier:#"theLabelCell"];
}
If you are not seeing any cells, then check whether numberofSections and numberOfRowsInSection delegate methods are not returning 0
When does your _arrayThatHasText get populated? The issue might very well be that the data source (_arrayThatHasText) is getting instantiated before the numberofSections and numberOfRowsInSection delegate methods are being called and then after these methods are called the data source is being populated with actual data -> which would result in the 0 values in the delegate methods as you are experiencing.
You might want to try putting a [self.tableView reloadData] call at the end of ViewWillAppear or in ViewDidAppear method and see if that helps.
I am a beginner in Objective-C & iPhone development.
I add dynamically cells in a TableView. I want to set labels's text properties with an array. I saw many tutorials, and I searched during several hours but labels are never filled.
My code is :
- (void)insertNewObject
{
for (NSInteger ic=0; ic<((pages.count)); ++ic) {
NSLog(#"%d", ic);
NSDictionary *monDico = pages[ic];
menu = [monDico objectForKey:#"Name"];
NSIndexPath *indexPathTable = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPathTable] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; // I try include & exclude : never call
}
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = menu[indexPath.row];
NSLog(#"%#%#", #"Cell Label = ", cell.textLabel.text);
return cell;
}
Please note that insertNewObject method is called during viewDidLoad execution.
I use a breakpoint in the cellForRowAtIndexPath method : it never calls ! I try with :
explicit calling
forcing reloadData method
but did not work too.
Can you please tell me why ?
Thanks in advance.
If cellForRowAtIndexPath is not being called then most likely you have not set:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [menu count]; // indicates the number of rows in your table view
}
This method needs to return the number of rows you expect to render within your table view. The default is 0 = no rows. I'm assuming you want to show all the items in your menu array so simply return [menu count].
Check this: UITableViewDataSource Protocol Reference
If you want to access to textLabel property of your cell, then it must be style of: UITableViewCellStyleDefault. Or, if you use storyboard, then set Cell's style to Basic.
And, of course, make sure that you have set delegate and datasource properties of your tableView.
- (void)viewDidLoad
{
[super viewDidLoad];
//...
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
------------------EDIT------------------
If you're using UITableViewController, then no more need to set delegate and dataSource properties manually, because they will automatically set by UITableViewController when your view did load.
If cellForRowAtIndexPath: method still not being called, then make sure that following methods that you implemented, both returns value >0:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Set a breakpoint before return and see returning values, or just NSLog them before returning.
I am downloading a string with the contents of a file online and separating these components by string into an array.
Once the download is finished I am calling a method to update my tableview to display these values.
- (void)updateTableView {
tableView.delegate = self;
tableView.dataSource = self;
}
Basically in this method I set the delegate and dataSource so the table view gets updated using this method...
- (UITableViewCell *)tableView:(UITableView *)tView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = [arrayDownloaded objectAtIndex:indexPath.row];
return cell;
}
But the issue is is that the table view doesn't get updated until I "touch" the view.
Like all the data is loaded and the method has been called but not until I tap on anywhere on the screen does the tableview get updated?
Why is this and how can I make it update as soon as I set the delegate and dataSource?
-Henry
Just reload the tabledata after finishing the downloading.
- (void)updateTableView
{
tableView.delegate = self;
tableView.dataSource = self;
[tableView reloadData];
}
I figured the solution. Rather than calling [self updateTableView]; to call the following method...
- (void)updateTableView {
[tableView reloadData];
}
I needed to do [self performSelectorOnMainThread:#selector(updateTableView) withObject:nil waitUntilDoneNO];
Some people are calling this an iOS bug since if you are not on the main thread numberOfRowsInSection gets called but cellForRowAtIndexPath doesn't.
Just a strange thing that I saw happening in my app. Hopefully this helps future developers.
-Henry
If you aren't already doing this somewhere, you need to call [tableView reloadData] after you've applied your changes.