How to append custom tableviewcells to tableview one by one - ios

I have two tableview controllers lets say PopoverElementsListTable ,ElementsViewTable. one tableview will be in popover state when I click on one of the PopoverElementsListTable cell a custom cell has to added to the ElementsViewTable.I'm able to append only one cell when I try to add another cell to ElementsViewTable its getting replaced with previous cell.
#pragma mark - TableView delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section{
if (tableView == PopoverElementsListTable) {
return [myArray count];
}
else if (tableView == ElementsViewTable) {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
if (tableView == PopoverElementsListTable) {
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}else {
NSLog(#"_selectedIndex %lu",(unsigned long)_selectedIndex);
if(_selectedIndex == 1){
AutoFillAddressFormElementcell * cell = [tableView dequeueReusableCellWithIdentifier:#"autoAddressCell"];
if (!cell) {
cell = [[AutoFillAddressFormElementcell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"autoAddressCell"];
}
return cell;
}else if(_selectedIndex == 2){
NSLog(#"Test # 123");
AddressSetterFormElementCell * cell = [tableView dequeueReusableCellWithIdentifier:#"setAddressCell"];
if (!cell) {
cell = [[AddressSetterFormElementCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"setAddressCell"];
}
return cell;
}else{
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = #"List";
return cell;
}
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
if(tableView == PopoverElementsListTable){
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %#",
(long)indexPath.section,(long)indexPath.row,cell.textLabel.text);
[_transarentView setHidden:true];
_selectedIndex = indexPath.row + 1;
NSLog(#"number %lu",(unsigned long)_selectedIndex);
[_displayFromElementTableView reloadData];
}
if(tableView == ElementsViewTable){
}
}
I know I'm able to append only one item because of return 1 in numberOfRowsInSection delegate. I tried replacing with another number but what I achieved is all the cells are identical.How can I get the dynamic count here? How to append customcells one by one which are unidentical.

You need to do it by identifying indexpath .
if (indexPath.row == 0) {
Customcell1 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}else if (indexPath.row == 1){
Customcell2 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}
return cell;
and so on....
You can check the table view too if you want.

Related

How To Get TableviewCell Selected Check Mark Row Values Using Objective C?

I need to create tableviewcell checkmark selected row title label and detail label values get after clicking the submit button.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil )
{
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %# %#",(long)indexPath.section,(long)indexPath.row,cell.sector_Label.text,cell.textLabel.text);
selectedIndex = indexPath.row;
[tableView reloadData];
}
- (IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
}
Check this:
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
if (selectedIndex >= 0) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"detailTextLabel: %#", cell.detailTextLabel.text);
NSLog(#"title: %#", cell.textLabel.text);
}
}
You can use indexPathsForSelectedRows
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.isSelected)
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else
{
[cell setSelected:YES animated:YES]
}
}
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
NSArray *indexes = [self.tableview indexPathsForSelectedRows];
if (indexes.count > 0)
{
//do your stuff as you get selected row index array
}
}

Cell at indexpath 0 not displaying correctly

I have a UITableView with sections inside of them. All works great, but I can't seem to figure out how to customize the very fist index path. For example, I know this is very easily achievable through a normal tableview like so:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
if (indexPath.row == 0)
{
cell.detailTextLabel.text = #"My Custom text";
NSLog(#"%#",pm1.customText1);
}
}
}
I have tried the above implementation and it does not seem to work for me. Is there a different approach for section headers to achieve the same result with a normal tableview? Do I need to inject a "fake" section in my dictionary?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0) {
cell.detailTextLabel.text = #"My Custom text";
NSLog(#"%#",pm1.customText1);
}
return cell;
}
Try this
The way you have it now the first cell is customize only when cell is nil.
You should move it out of the if statement.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//check for first cell
if (indexPath.row == 0) {
cell.detailTextLabel.text = #"My first Cell";
NSLog(#"%#",pm1.customText1);
}else{
cell.detailTextLabel.text = #"Other cells";
NSLog(#"other cells");
}
return cell;
}

Multiple UITableViewCells different fields per row

I have 2 tableViews, the first only loads a list from an array.
The other 1, show details per row. But it shows a crash report:
'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath: Exception'
What seems to be wrong with my code? I want to show each row a different detail that came from the same sqlite row.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"courseCell"];
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName"];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings"];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView:cellForRowAtIndexPath: method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new cell for the table view. This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you did not register a class or nib file, this method returns nil.
If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.
You need to create different cells for each tableview, Try to use the above code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else
{
for(UIView *view in cell.contentView.subviews)
{
[view removeFromSuperview];
}
}
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else
{
for(UIView *view in cell.contentView.subviews)
{
[view removeFromSuperview];
}
}
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName"];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings"];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
Please cross check either one of your table is returning more number of rows in numberOfRowsInSection method . It might be that you haven't put check on this method as both of the table are returning different number of rows .
First, check that your numberOfRowsInSection returns the correct number of rows for your table. I would think this would be it.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(tableView == self.cTableLabel)
{
return [self.course count];
}
//tableView 2
if(tableView == self.jTableLabel)
{
return 2;
}
return 0;
}
Otherwise I would set a break point on return 0; or NSLog before it in cellForRowAtIndexPath, because my guess is neither if block is hit and you are returning zero. Does it get triggered?
Edit - Ah, I think I see dequeueReusableCellWithIdentifier: will return a nil cell if you haven't set one up yet. Try using dequeueReusableCellWithIdentifier: forIndexPath: instead. This will always return a valid cell assuming you called registerClass:[UITableViewCell class] forCellReuseIdentifier: first.
Give this a shot:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"courseCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"JobName"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"JobEarnings"];
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"courseCell" forIndexPath:indexPath];
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName" forIndexPath:indexPath];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings" forIndexPath:indexPath];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
Also registerClass:[UITableViewCell class] forCellReuseIdentifier: could be called in your init, it only needs to be declared once.

How to use multiple reusable TableViewCells

I like to add multiple reusable UITableViewCells to a TableView. I am using this code to do this, but it won't work, it only shows the first cell.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
static NSString *costumeCell1 = #"Cell1";
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1];
if (!cell1) {
cell1 = [[AppDetailCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell1];
}
return cell1;
}
if (indexPath.row == 1) {
static NSString *costumeCell2 = #"Cell2";
AppDetailCell2 *cell2 = [tableView dequeueReusableCellWithIdentifier:costumeCell2];
if (!cell2) {
cell2 = [[AppDetailCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell2];
}
return cell2;
} else {
return nil;
}
}
If you set the reuse identifiers properly, you should change this code part
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1];
if (!cell1) {
cell1 = [[AppDetailCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell1];
}
with this
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1 forIndexPath:indexPath];
There is no need if(!cell1), because dequeueReusableCellWithIdentifier: forIndexPath: method never returns nil, as I said before that properly reuse identifier set is important.

Working with some of UITableViewCell

How to select several UITableViewCell (as a checkmark but with my own style) and then do something with selected items?
As a checkmark (or something else) I would like to use UIImageView:
To add to Pandu1251's answer, if you want to use your own check mark image, you can set a custom accessory view and follow the same logic that he has specified.
To set a custom accessory view, use
cell.accessoryView = myAccessoryView; //myAccessoryView is a UIImageView holding your custom check mark image
-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath
{
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
if (thisCell.accessoryType == UITableViewCellAccessoryNone)
{
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
for(int i=0;i<[Array count];i++)
{
thisCell.accessoryType = UITableViewCellAccessoryNone;
}
thisCell.accessoryType = UITableViewCellAccessoryNone;
}
}
Now try this......
Just do as follow. For that you have to take NSMutableArray. i have taken arrMethodsToBeStored here.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.textColor=[UIColor darkGrayColor];
cell.textLabel.font= [UIFont fontWithName:#"Arial Rounded MT Bold" size:15.0];
Scope_RepairMethod *scpObj=[repairMethodArr objectAtIndex:indexPath.row];
cell.textLabel.text= scpObj.strRepairMethod;
if([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// NSString *selID;
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
Scope_RepairMethod *scpObj=[repairMethodArr objectAtIndex:indexPath.row];
if (newCell.accessoryType == UITableViewCellAccessoryNone)
{
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
[arrMethodsToBeStored addObject:scpObj.strRepairMethod];
}
else
{
newCell.accessoryType = UITableViewCellAccessoryNone;
[arrMethodsToBeStored removeObject:scpObj.strRepairMethod];
}
NSLog(#"selected method arr==== %#",arrMethodsToBeStored);
// I want to enable my save button only if one or more values from table are selected
if(arrMethodsToBeStored.count > 0)
saveBtn.enabled=true;
else
{
saveBtn.enabled=false;
}
}

Resources