I have a #property(nonatomic,strong) NSMutableArray *categoriesArray; that gets populated with categories in the - (void)viewDidLoad method. However I believe - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathis getting executed before the categories can be populated in my categoriesArray. Where do I insert my code to populate the categoriesArray so that it will be populated when it is called for the table cell method?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Category Cell" forIndexPath:indexPath];
NSDictionary *category = self.categoriesArray[indexPath.row];
//cell.textLabel.text = [category valueForKey:#"categoryName"];
return cell;
}
You just need to call [self.myTableView reloadData]; when you have your categories array populated. This will reload all the data that is used to construct the table by calling the table view data source and delegate methods (one of them is your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Also, make sure that you are setting the delegate and dataSource properties of tableview correctly.
More information here: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/reloadData
https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/dataSource
Related
I am creating an app where users can store an object in Core Data. I have the Objects being pulled into a UITableView and everything is working correctly there. I now want to separate the objects into a possible of 1-3 different sections based on choices in a UISegmentedControl.
Currently I have this to create the 1 section and populate the cells of that section with my objects
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.fetchedDiscs.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DiscCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//Configure Cell
Disc *currentDisc = [self.fetchedDiscs objectAtIndex:indexPath.row];
cell.textLabel.text = currentDisc.name;
cell.detailTextLabel.text = currentDisc.brand;
return cell;
}
So the main question is how to dynamically change the number of sections and number of rows in section?
The Segmented control returns values such as Option 1, Option 2, Option 3. The only way I can think of is to loop through my fetchedDiscs array and separate that into an array for each section. Then I can return the number of arrays if they exists and I can get the count of each array to get the number of rows in each section. But then I get to the problem of How to get the CellForRowAtIndextPath to work correctly with three arrays.
Basically there has to be a better more logical way to do this. I am just not sure how.
Let, you have a dictionary named dataSource that contains 'x' number of array as value for key "key1", "key2", .. "keyX". You can do this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[dataSource allKeys] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Get the array object form key. I am considering 'keySection' as an example
return [[dataSource objectForKey:#"keySection"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DiscCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [[dataSource objectForKey:keySection] objectAtIndex:indexPath.row]
return cell;
}
Note: I wrote the code in this editor, excuse any mistakes, I just tried to share the idea. Hope this helps.. :)
Is it possible to highlight multiple UITableViewCells? Something like a filter table. If the user taps on row 0, it gets highlighted. Then user taps on row 1 and that also gets highlighted but row 0 stays highlighted also. I haven't seen any examples for this.
I have a dictionary with 5 items which can get selected, values of which are either yes or no to keep track which ones are highlighted.
I used (UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath and set it to nil but now I can't unselect rows. Any help please?
What you can do to implement this is keep a track of the selected indexes and change the backgroundcolor of table viewCell accordingly, for example:
Declare an Array as SelectedIndexes
Then in your didSelectRowAtIndex method just do this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if([selectedIndex containObject :indexPath]){
[selectedIndexes removeObject:indexPath];
}else{
[selectedIndexes addObject:indexPath];
}
[tableView reloadData];
}
And then In your CellForRowAtIndexPath Method do this
(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([selectedIndex containObject :indexPath]){
cell.backgroundColor=highlightedColor;
}else{
cell.backgrounfColor=NormalColor;
}
}
Hope this Helps
I have a TableView with three sections. Section one and two can be deleted, (delete with swipe)
section three can't. My problem now is that when I swipe on a cell in the third section, it gets selected. I tried deselecting it when "canEditRowAtIndexPath" is called(and it really gets called), but that doesn't work and the cell remains selected. My "canEditRowAtIndexPath" looks like this:
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section == 2)
{
return NO;
}
return YES;
}
I found ( in my opnion ) a better solution to this matter
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Right)
I hope that helps!!
Regards
You may check and close the 3rd section cell selections in -(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath by using tableViewCell.selectionStyle = UITableViewCellSelectionStyleNone;
You should call [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; in this method -
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Or in -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Set selection style none. cell.selectionStyle = UITableViewCellSelectionStyleNone;
Use this delegate method of UITableView
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I found a great workaround.
A swipe on the cell, forces the app to call viewWillAppear.
Add [self.tableView reloadData];into that method and the selected state will be removed.
I'm parsing a bunch of json objects from my API and place it into a table view. When I hit the a row I want it to parse an object from the API out of an array and forward it to another view so one can get more details.
If I place the code how I think it works in the cellForRowAtIndexPath everything is fine but by the time I place an NSLog in the didSelectRowAtIndexPath and make him display the ID I parsed for the specific row I don't get anything?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *neuheitenCell = #"neuheitenCell";
CJHomeTableCell *cell = [tableView dequeueReusableCellWithIdentifier:neuheitenCell];
sstring = [[idArray objectAtIndex:indexPath.row] objectForKey:#"ware_id"];
//NSLog(#"Selected item with id: %#",sstring);
return cell;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"stuff: %#", sstring);
}
Thanks in advance
Because you used didDeselectRowAtIndexPath: instead of didSelectRowAtIndexPath:.
Note the spelling.
I need to have a custom cell height for all of my cells in my UITableView. In this method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
I try this:
if ([[tableView cellForRowAtIndexPath:indexPath] reuseIdentifier] == #"imageCell")
As I have 3 different cells setup with different identifiers in my storyboard. However my app just crashes here with EXC_BAD_ACCESS.
Any idea why?
Thanks.
You're comparing a string, so you should be using isEqualToString:
if ([[[tableView cellForRowAtIndexPath:indexPath] reuseIdentifier] isEqualToString:#"imageCell"])
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
you are supposed to calculate the height for you row, not to get the Cell of your tableView.
In my opinion, in the lifeCycle of a TableView delegate, the 1st step (before allocating each UITableViewCell), the TableView delegate call heightForRowAtIndexPath for each row (but at this moment, the UItableViewCell are not allocated). The, in a 2nd step, the TableView call
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
to create UitableView Cells.