Calling UITable View Delegate Method - iphone

I'm working with UITableView in UIViewController..I am using the following delegate methods.....
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Once I load the view I find all delegates has been called..... But I need to call these methods in a button click.....
I tried in this way....
[self tableView:table numberOfRowsInSection:rows];
[self tableView:table cellForRowAtIndexPath:path];
I find that these methods has been called,but nothing happened (code inside these delegates doesn't works).... I don't knw why??? Any suggestions???

Write the code inside the button click function it will call all the delegates of the tableview
[self.tableView reloadData];
or complete code to your solution is:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
customCell *cell = [[customCell alloc]init];
if (cell == nil) {
cell = [[[customCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:#"customCell" owner:self options:nil];
cell = (customCell *)[topLevelObjects objectAtIndex:0];
int count=0;
for(id currentObject in topLevelObjects)
{
count++;
if([currentObject isKindOfClass:[customCell class]])
{
cell= (customCell *)currentObject;
UILabel *sName = (UILabel *)[cell.contentView viewWithTag:1];
//Checking the flag that is set in the btnClicked event
if (flag) {
sName.hidden=YES;
}
else{
sName.text = [arrayResult objectAtIndex:indexPath.row];
}
}
}
return cell;
[topLevelObjects release];
[cell release];
}
-(IBAction) btnClicked:(id) sender{
flag=YES;
[self.tableView reloadData];
}
Try this it will work..

Related

How to maintain state of selection of row in table view?

i am a beginner in xcode. I am creating a questionnaire type list with multiple rows in scroll. But when I select a row and scroll it doesn't retains its state and when I come back, it also loses its selection. So anyone please kindly let me know how to achieve that,i have tried something like this,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(val==1)
{
checkedArr=[[NSMutableArray alloc] init];
for (int i = 0; i<17; i++)
{
[checkedArr addObject:#"1"];
}
NSLog(#"Checked arr size %i",[checkedArr count]);
return 17;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%i",indexPath.row];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
}
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:18.0];
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = [UIColor colorWithRed:99/255.0f green:209/255.0f blue:248/255.0f alpha:1.0];
cell.selectedBackgroundView = selectionColor;
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
cell.textLabel.frame=CGRectMake(75.0, 50.0, 150.0, 20.0);
cell.textLabel.text=[listArray objectAtIndex:indexPath.row];
NSLog(#"Checked arr size %i",[checkedArr count]);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cell=[questionTable cellForRowAtIndexPath:indexPath];
[checkedArr replaceObjectAtIndex:indexPath.row withObject:#"0"];
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{[questionTable deselectRowAtIndexPath:indexPath animated:YES];
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
NSLog(#"Val is %i",val);
NSLog(#"selected is %#",[listArray objectAtIndex:indexPath.row]);
// NSLog(#"Checked arr descripton %#",[checkedArr description]);
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryView = UITableViewCellAccessoryNone;
}
In my application i used same code for check mark as accessoryType,check this.
take it in .h file mutable array arSelectedRows;
- (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];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
//Do anything you want for cell here
if([arSelectedRows containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are :%#",arSelectedRows);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
EDIT
//if you want only single check mark
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arSelectedRows removeAllObjects];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are:%#",arSelectedRows);
[self.tableview reloadData];//Reload your tableview here
}
it will help you.
First your cellForRowAtIndexPath method create new cell each time whenever you scroll up/down tableView, it is very bad for memory management.
Just remove [questionTable deselectRowAtIndexPath:indexPath animated:YES] in your cellForRowAtIndexPath method
I think you need to use this api below:-
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition
If you are using dynamic cells, and updating your row with some kind of class variable like a NSArray, you might have set your variable to weak instead of strong.

How to Set (TableView cellForRowAtIndexpath) activity in A Button?

Hey Guys, please let me know how can I set this code action in to an UIButton action...
Here is the code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *myIdentiFier=#"myIdentiFier";
myCell *cell=[tableView dequeueReusableCellWithIdentifier:myIdentiFier];
if(!cell){
//cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:myIdentiFier];
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"myCell" owner:self options:nil];
for(id obj in nib){
if([obj isKindOfClass:[myCell class]]){
cell=(myCell *)obj;
break;
}
}
}
NSDictionary *diction=(NSDictionary*)[content objectAtIndex:indexPath.row];
[cell.contentView setBackgroundColor:[UIColor orangeColor]];
cell.empID.text=[diction objectForKey:#"empid"];
cell.empName.text=[diction objectForKey:#"empname"];
cell.designation.text=[diction objectForKey:#"empdesignation"];
cell.teamName.text=[diction objectForKey:#"empteam"];
return cell;
}
i want to set above action in my button..
- (IBAction)displayRecord:(id)sender {
}
please tell me ...
you can call
[tableview reloadData]
than cellForRowAtIndexPath is called.
simply u can do as follow
- (IBAction)displayRecord:(id)sender {
[yourTablename reloadData];
}

Multiple accessory checkmarks displayed on a UITableView

I have a UITableView that displays checkmarks when a row is selected. The problem is that when the table view scrolls multiple checkmarks are shown when only one was ever row selected. The problem arises as the table scrolls and the dequeue process occurs. Here's my cellForRowAtIndexPath: method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRed:204.0/255.0 green:56.0/255.0 blue:55.0/255.0 alpha:1];
}
// Get item from tableData
NSDictionary *item = (NSDictionary *)[displayItems objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"key"];
[cell.textLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
return cell;
}
and didSelect method:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
selectedCityTableString = cell.textLabel.text;
cellAccessoryImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon-tick.png"]] ;
cellAccessoryNoneImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#""]] ;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
// cell.accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryView = cellAccessoryImageView;
if (prev!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]];
//cell.accessoryType=UITableViewCellAccessoryNone;
cell.accessoryView = cellAccessoryNoneImageView;
prev=indexPath.row;
}
}
else{
// cell.accessoryType=UITableViewCellAccessoryNone;
cell.accessoryView = cellAccessoryNoneImageView;
}
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *mutCityStr = [[selectedCityTableString stringByReplacingOccurrencesOfString:#" " withString:#"+"] lowercaseString];
// NSString *mutCityStr = #"c";
[prefs setObject:mutCityStr forKey:#"selectedCityTableString"];
[prefs synchronize];
#ifdef DEBUG
NSLog(#"mutCityStr is %#",mutCityStr);
NSLog(#"selectedCityTableString is %#",selectedCityTableString);
NSLog(#"posting notification from TWO TABLES");
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:#"TTSelectedList" object:selectedCountryTableString];
}
Supposing you have a property (attribute) called selectedRow use the combination of this methods:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if (indexPath.row == self.selectedRow) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// If there is a cell selected deselect
if (self.selectedRow != NSNotFound) {
NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:self.selectedAQIType inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:previousIndexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Select the touched cell
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.selectedRow = indexPath.row;
}
In your .h file
int selectedRow;
In your .m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// your other code for cell init,etc
int row = [indexPath row];
cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedRow = [indexPath row];
[tableView reloadData];
}
Hope this helps!!!
UITableView's delegate method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath reuses the cell based on the reuseidentifier. Hence you need to reset the entire cell contents to default.
In your case uncheck the cell's view before you return the cell.
To solve this problem, store your selected row indexes in one NSArray. (in didSelectRowAtIndexPath method)
And in cellForRowAtIndexPath method, check whether indexPath.row is available in that array then enable your checkmark, else disable.
Note: Maintain array for check-uncheck event
Hope this will help you.

UITableView Cells get reordered after editing the cell

In my app, You can tap a cell, and it brings up a new view. You can edit the tableviewCell's textLabel, and save it. But when you switch views and come back to the tableView, the cells are in a different order. What could be the reason for this?
Here is my Code:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * identifier = #"identifier";
self.cell = [tableView dequeueReusableCellWithIdentifier:identifier];
h = [self.tableArray objectAtIndex:indexPath.row];
NSString *brandModel = [[h.brand stringByAppendingString:#" "] stringByAppendingString:h.model];
self.cell.mainLabel.text = brandModel;
self.cell.nicknameLabel.text = handguns.nickname;
return self.cell;
}
If you are reloading tableView after saving UITableView cell then It will be reordered as initial because array from which you are setting cell data is as it is.You can change only table View cells not array data position in an array.
Below I have written a UITableView code to move cells and it is working fine after pushing view.If I remove reload method from viewWillAppear:
#import "MoveCellViewController.h"
#interface MoveCellViewController ()
#end
#implementation MoveCellViewController
- (void)viewDidLoad
{
UIBarButtonItem *left=[[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStyleBordered target:self action:#selector(edit)];
self.navigationItem.leftBarButtonItem=left;
myArray=[[NSMutableArray alloc]init]; //mutable array;
myArray=[NSMutableArray arrayWithObjects:#"Aman",#"Ankit",#"Sumit",#"Hercules",#"Jackie Chan", nil];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)edit
{
if (self.navigationItem.leftBarButtonItem.title==#"Edit") {
self.navigationItem.leftBarButtonItem.title=#"Done";
[_tableView setEditing:YES];
}else
{
[_tableView setEditing:NO];
self.navigationItem.leftBarButtonItem.title=#"Edit";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArray count];
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cellIdentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.userInteractionEnabled=YES;
cell.textLabel.text=[myArray objectAtIndex:indexPath.row];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
id ob = [myArray objectAtIndex:destinationIndexPath.row];
[myArray replaceObjectAtIndex:destinationIndexPath.row withObject:[myArray objectAtIndex:sourceIndexPath.row]];
[myArray replaceObjectAtIndex:sourceIndexPath.row withObject:ob];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NextViewController *nx=[[NextViewController alloc] init];
[self.navigationController pushViewController:nx animated:YES];
}
#end
This is working code and will not change after push view controller.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
h = [self.tableArray objectAtIndex:indexPath.row];
NSString *brandModel = [[h.brand stringByAppendingString:#" "] stringByAppendingString:h.model];
self.cell.mainLabel.text = brandModel;
self.cell.nicknameLabel.text = handguns.nickname;
return self.cell;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:nil];
}
Write rest of the code here
}

Load more cells "willDisplayCell" Problem

i have a problem with willDisplayCell it doesn't stop fetch Xml from the url
my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [itemsToDisplay count] + 1;
}
- (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];
}
if (indexPath.row == [itemsToDisplay count]) {
cell.textLabel.text = #"Load More...";
} else {
MWFeedItem *item = [itemsToDisplay objectAtIndex:indexPath.row];
cell.textLabel.text = item.title;
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [itemsToDisplay count]) {
// Parse
NSURL *feedURL = [NSURL URLWithString:#"http://gdata.youtube.com/feeds/api/users/RayWilliamJohnson/uploads?v=2&alt=rss&sort_field=added&start-index=21&max-results=20"];
feedParser = [[MWFeedParser alloc] initWithFeedURL:feedURL];
feedParser.delegate = self;
feedParser.feedParseType = ParseTypeFull; // Parse feed info and all items
feedParser.connectionType = ConnectionTypeAsynchronously;
[feedParser parse];
[self.tableView reloadData];
}
}
its look like he is in kind of loop that doesnt stop fetch xml
so how can i fix it so i will only called once?
tnx
The problem is that you have called reloadData within tableView:willDisplayCell:. reloadData will cause every UITableViewCell to get drawn again, means willDisplayCell will get called for every cell that will be visible on screen. Seems to me like you have an infinite loop there.
tableView:willDisplayCell: is definitely the wrong place to be doing that XML parsing. willDisplayCell should just be used to prepare the UI. I can't say for certain, but perhaps a better place to the XML parsing would be in your view controller's init method.