On my UITableViewI am using custom UITableViewCells. Each of these cells has a number of labels. When the user selects a cell, I need to capture the contents of just one of these labels, but I don't know how to do that. Here is my code. The line that I am using to attempt to get this label text is basically pseudo-code that clearly won't compile. Can somebody please tell me what I need to do here? Thanks!
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
Groups *group = [self.fetchedObjects objectAtIndex:indexPath.row];
cell.groupDescriptionLabel.text = group.group_descr;
cell.groupIDLabel.text = [group.group_id stringValue];
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// capture the user selection
Groups *group = [self.fetchedObjects objectAtIndex:indexPath.row];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *selection = selectedCell.groupDescriptionLabel.text; //<-- pseudo-code
NSLog(#"%#", group.group_descr);
...
}
It's generally a bad idea to get data out of the view. You shouldn't really be using any view objects as a way of storing information.
You are already getting the string when you are in the cellForRowAtIndexPath method.
You should be able to do the same in didSelectRowAtIndexPath to get the same string.
That way you don't have to get the text out of the label at all.
Thanks
If you know that celForRowAtIndexPath is going to be returning one of your custom cell types instead of a generic UITableViewCell, cast the result to your custom cell class:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// capture the user selection
MyCellClass *selectedCell = (MyCellClass *) [tableView cellForRowAtIndexPath:indexPath];
NSString *selection = selectedCell.groupDescriptionLabel.text; //<-- pseudo-code
NSLog(#"%#", selection);
//...
}
Related
I have two different custom TableView Cells. That said, when the first cell type is returned, I want the other returned immediately after. Technically, the below code is what I want to occur:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier forIndexPath:indexPath];
UniversalAlertTableViewCell *cellUni = (UniversalAlertTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifierUni forIndexPath:indexPath];
return cell;
return cellUni;
}
However, as we know, code stops executing after the first return cell. How can I accomplish this?
You can only return one specific type at a time. Use the indexPath parameter to decide which one to return.
The following code is a rough idea of what you need. It's up to you to adapt the if statement based on your actual needs.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier forIndexPath:indexPath];
// configure cell based on data from your data model for this indexPath
return cell;
} else {
UniversalAlertTableViewCell *cell = (UniversalAlertTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifierUni forIndexPath:indexPath];
// configure cell based on data from your data model for this indexPath
return cell;
}
}
Your question is very interesting. First clarify your needs.
I guess your demand is probably like this, and once the layout is displayed, switch to another layout. Let me talk about my habit of using tables. I am used to using data to control display and animation behavior. For your needs, I can use two data sources, corresponding to two kinds of cells. After one data source is displayed, immediately switch to another data source, and finally refresh the table.
The code is probably like this, you need a data source array models, and then each cell corresponds to a data source.
#property (strong, nonatomic) NSArray *models;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
ChatModel *model = ChatModel.new;
self.models = #[model];
[self.tableView reloadData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UniversalAlertModel *universalModel = UniversalAlertModel.new;
self.models = #[universalModel];
[self.tableView reloadData];
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.models.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
id model = self.models[indexPath.row];
if ([model isMemberOfClass:ChatModel.class]) {
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier forIndexPath:indexPath];
// Set UI display according to model
return cell;
}else if ([model isMemberOfClass:UniversalAlertModel.class]){
UniversalAlertTableViewCell *cellUni = (UniversalAlertTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifierUni forIndexPath:indexPath];
// Set UI display according to model
return cellUni;
}
}
You cannot return two custom cells at the same time. It is not possible, because the delegate only runs one time per row. You can return a different cell on a different row or section.
I have been looking for answers for more than 2 days now. It just does not seem to solve.
Here is the code for cell
- (myCustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomData *m = (CustomData *)[self.allCustomData objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"customCell";
myCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithRed:255.0f green:255.0f blue:255.0f alpha:1]];
[cell.customTitle setText:m.name];
[cell.customStatus setText:#"Download"];
NSLog(#"%#",cell.customTitle.text);
return cell;
}
'cell' never returns nil. the log always prints the correct text. But the cells appear empty for some reason. On load I notice the first cell appears empty, and then on scroll, randomly 2-3 cells of any order become empty. The first cell often appears back on scroll.
I can't seem to understand what the issue could be.
UPDATE
Here are two screen shots. First one is how the table loads, I have put a background color just for debugging purpose. As you see the first cell is not showing up.
The one below is the second screenshot where I changed the orientation and scrolled a bit. You see how the first cell magically appears and the second goes away.
Also for debugging purpose, I added these two methods.
- (void)tableView:(UITableView *)tableView willDisplayCell:(dtEditionCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"Display %# %d %f",cell.editionTitle.text,indexPath.row,cell.frame.origin.x);
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(dtEditionCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"End Display %# %d %f",cell.editionTitle.text,indexPath.row,cell.frame.origin.x);
}
The log prints as expected. All cells are visible with correct text.
I don't know if it has something to do, but the method you show is not exactly the one used by the tableview. Here is how I do it with custom cells. I'm doing it a lot and works fine:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TextCell *cell = [tableView dequeueReusableCellWithIdentifier:#"textCellId" forIndexPath:indexPath];
TextFieldContent *cellContent=[[self.dataSource objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.titleLabel.text=cellContent.titleLabel;
cell.textField.placeholder=cellContent.placeHolder;
cell.textField.tag=cellContent.tag;
cell.textField.keyboardType=UIKeyboardTypeDecimalPad;
cell.textField.delegate=self;
return cell;
}
TextFieldContent is a cutom object that hold all the properties of the custom cell. For easier implementation.
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 am from C# background and now learning objective C.
I created two NSArrays 1.optionsLabelArray and 2.optionsLabelSubtitleArray initially with two elements each (optionsLabelArray=>Yes & No) and optionsLabelSubtitleArray(acceptable and action). Now requirement changed and I have to add one more item and I am doing it like below. But It still shows only two elements.
I tried using NSMutableArray , no luck. Looks like it's a small issue but couldn't figure it out.. any ideas will be appreciated.
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
optionsLabelArray = [[NSArray alloc] initWithObjects:#"Yes", #"No",#"No" ,nil]; // here is problem
optionsLabelSubtitleArray = [[NSArray alloc] initWithObjects:#"Acceptable",#"Action required",#"No", nil]; // here to
static NSString *CellIdentifier = #"CheckerCell";
CustomCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.optionLabel.text = [optionsLabelArray objectAtIndex:indexPath.row];
cell.optionLabelSubtitle.text = [optionsLabelSubtitleArray objectAtIndex:indexPath.row];
return cell;
}
You need to update the implementation of your - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method to support more rows. To do so you probably want to have an implementation where the array is either an instance variable of the class or otherwise consistent between the two methods.
you need implement following method and return 3 when you increase cell count
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
see more on https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:
I have a UITableView and I am trying to get the text of all the selected rows when a button is pressed. Here's what I have so far:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
[selectedRows addObject:selectedCell.textLabel.text];
}
selectedRows is an array.
Here is my button press function where I need access to the checked row titles:
- (IBAction)selectList:(id)sender {
NSLog(#"%#", selectedRows);
}
This doesn't work for me because if a user unchecks a row and then clicks the submit button - it is not reflected in the array. I would appreciate some help with this. thanks.
Instead of dealing with keeping tabs on what is/isn't selected at any given moment, why not just wait until it's time to select the list to generate it and let the table keep track of what's selected. (provided it isn't some massive amount of data) You could loop through the index paths of your table's selected cells and pull the string you're looking for directly out of the datasource.
- (IBAction)selectList:(id)sender
{
NSMutableArray *arrayOfText = [NSMutableArray new];
for (NSIndexPath *idx in self.tableView.indexPathsForSelectedRows) {
[arrayOfText addObject:dataSource[idx.row]];
}
NSLog(#"%#",arrayOfText);
}
You could add a didDeselectRowAtIndexPath function and remove the item from the array.
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
[selectedRows removeObject:selectedCell.textLabel.text];
}