problem with check mark in iphone - iphone

I am new to the iPhone. I'm creating an application. For that I want to send friends an invitation from my app to a Facebook profile. My Facebook friends are listed in a TableView.
I want to select 40 fiends at a time and send invitation to friends' wall.
In my app I wrote to display my friends:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Displayfriendscell";
Displayfriendscell *cell = (Displayfriendscell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[Displayfriendscell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell...
NSString *name=[Friendsarray objectAtIndex:indexPath.row];
//NSLog(#"name is%#",friendid);
cell.nameLabel.text = name;
return cell;
}
What should I do for that? I have no idea about check marks and their workings. I just want an idea about it. Can anybody help me implement this?

Basically, cells have an accessoryType for checkmark you can use:
Unselected cells start off as no accessory type:
cell.accessoryType = UITableViewCellAccessoryNone;
When a cell is selected:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
Also, somewhere you'll need to keep track of which items in your datasource (I.e. Friendsarray) have been selected, since the UITableView will reuse it's cells. For example another array filled with NSNumbers - 0 for unselected and 1 for selected (another example would be to change Friendsarray to a 2 dimensional array. Or, since your integrating with facebook, it probably would be best in the long run to create a class of 'friend' and make an array of that, where one of the fields is 'selected').
Since UITableView reuses cells as you scroll the table, your cellForRowAtIndexPath will need to check with your array to see if the cell should be set to checked or unchecked.
The code for selecting the cell goes in:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
When the user completes you'll loop through your datasource (your array or whatever) and get the selected friends.
Hope that's the guidance you're looking for.

What you want to implement is multiple row selection. Look at these links
Is it possible to configure a UITableView to allow multiple-selection?
Select multiple rows in UITableview

This might help you:
in your cellForRowAtIndexPath method do like this:
NSString *name=[Friendsarray objectAtIndex:indexPath.row];
UILabel *lblName = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 250, 20)];
lblName.text = name;
[cell addSubview:lblName];
UIButton *btnCheck = [UIButton buttonWithType:UIButtonTypeCustom];
btnCheck.frame = CGRectMake(290, 8, 16, 16);
[btnCheck setImage:[UIImage imageNamed:#"checkbox.png"] forState:UIControlStateNormal];
[btnCheck setTitle:#"0" forState:UIControlStateNormal];
[btnCheck addTarget:self action:#selector(btnClicked:)forControlEvents:UIControlEventTouchUpInside];
btnCheck.tag = indexPath.row+1;
[cell addSubview:btnCheck];
// in selector method (btnClicked):
-(void)btnClicked:(id)sender
{
UIButton *btnTemp = (UIButton*)sender;
UIButton *btnSelected = (UIButton*) [self.view viewWithTag:btnTemp.tag];
NSString *strTitle = btnSelected.titleLabel.text;
if([strTitle isEqualToString:#"0"])
{
[btnSelected setTitle:#"1" forState:UIControlStateNormal];
[btnSelected setImage:[UIImage imageNamed:#"checkbox-checked.png"] forState:UIControlStateNormal];
}
else
{
[btnSelected setTitle:#"0" forState:UIControlStateNormal];
[btnSelected setImage:[UIImage imageNamed:#"checkbox.png"] forState:UIControlStateNormal];
}
}
// use two image, one is small sqaure and another with tickmarked image

Related

When we scroll custom table then cell content change in iPhone

hello friends I have created custom table and add all needed delegate and datasource for table then this is working good but when we scroll my table then content change like this is code...
Table_worklist=[[UITableView alloc]initWithFrame:CGRectMake(10,480,750,130)style:UITableViewStylePlain];
Table_worklist.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
Table_worklist.delegate=self;
Table_worklist.dataSource=self;
Table_worklist.layer.borderWidth = 2.0;
Table_worklist.layer.borderColor = [UIColor grayColor].CGColor;
[ScrollView addSubview:Table_worklist];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell== nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UITextField *resultval=[[UITextField alloc]initWithFrame:CGRectMake(510,10,120,30)];
resultval.tag=1;
resultval.font = [UIFont boldSystemFontOfSize:12.0];
//the horizontal alignment of the text
resultval.textAlignment = NSTextAlignmentCenter;
resultval.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter;
resultval.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
resultval.delegate =self;
if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Numerical"])
{
imageLayer = field.layer;
[imageLayer setCornerRadius:02];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor lightGrayColor]CGColor];
}
else if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Words"]||[[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Comment"])
{
imageLayer = field.layer;
[imageLayer setCornerRadius:06];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor blackColor]CGColor];
UIButton *CheckMark=[[UIButton alloc]initWithFrame:CGRectMake(540,10,30,30)];
CheckMark.tag=1;
[CheckMark setImage:[UIImage imageNamed:#"DownTriangle1"]forState:UIControlStateNormal];
imageLayer = CheckMark.layer;
[imageLayer setCornerRadius:02];
[imageLayer setBorderWidth:1];
imageLayer.borderColor=[[UIColor blackColor] CGColor];
[cell.contentView addSubview:CheckMark];
}
[cell.contentView addSubview:resultval];
}
return cell;
}
this show right data for first 3or4 cell(because table height 130 so show only 3 cell at a time )for these 3 cell my table show right data ...for example
if([[NSString stringWithFormat:#"%#",[[TestSample objectAtIndex:indexPath.row]valueForKey:#"ResultType"]]isEqualToString:#"Numerical"])
{ }
then data is numerical go this if condition other wise go else condition......
but when we have for more cell like as 7-8 cell then when we scroll these cell so what happened suppose at cell-4 my controller go else if condition forComment and word data .........so at last cell -8 got numerical data so controller go in if condition but check mark button which was created in if else condition which show on my if condition data ......so i don't know what happened
when we scroll how to change my condition ......
Actually i thing when last created else if condition (which create uibutton checkmark)on cell-4 which are apply on cell-8...........but controller go in right place in if condition at cell-8 .....but last time created checkmark button generated on cell-8 ......
how to solve this problem....
Before You follow my Answer i want to tell you that following code is bad for memory management because it will create new cell for each rows of UITableView, so be careful for it.
But it is better to use, When UITableView Have Limited rows (about 50-100 may be ) then following code is helpful in your case, use it if is it suitable for you.
- (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:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// Put your code here
}
return cell;
}
If you have limited rows then this is best code for you.

iphone development: changing the button image on tableviewcell

In my app I am facing with a really weird problem. I am trying to solve it for hours but could not find what is the problem so far.
Well, I have a tableview with custom cells. and each cell I have a button. It is is like an empty box. When the button pressed, I want to change the related cell image of that button. Actually I successfully do that but somehow, some other cell's button images are also changing and I could not figure out why. Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//create new cell
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell.tickButton setTag:indexPath.row];
[cell.tickButton addTarget:self action:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside];
//cell has 2 label so I filled them with the contents of my object array that part is working with no problem
cell.leftLabel.text = [NSString stringWithFormat:#"%#", [[contacts objectAtIndex:indexPath.row]name]];
cell.rightLabel.text = [NSString stringWithFormat:#"%#", [[contacts objectAtIndex:indexPath.row]email]];
return cell;
}
in my buttonWasPressed method I simply do:
-(IBAction)buttonWasPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
}
As I said before it works but also changes some other buttons images and also when I scroll down and get back to the initial position I see that some button images are changed.
You can access that cell and can change the button image as :
-(IBAction)buttonWasPressed:(id)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:your_row inSection:your_section];
UITableViewCell *currentCell = [table cellForRowAtIndexPath:indexPath];
UIButton *button = (UIButton *)[currentCell viewWithTag:(UIButton *)sender.tag];
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
}
Hope it helps you.
You can deal with touch within CustomCell class. Just move method -(IBAction)buttonWasPressed:(id)sender within your custom class and add
tickButton addTarget:selfaction:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside in init method.
The problem is calling
[cell.tickButton addTarget:self action:#selector(buttonWasPressed:)forControlEvents:UIControlEventTouchUpInside];
method.
You add target everytime when your cells are reused and remove never. So your buttons have many targets and action method get called multiple times respectively. It may cause a memory leak.
Just put the addTarget method in if clause.
It will solve your one problem, which is your method get called multiple times. But when the cell is reused the button has the changed image. You need to set it back.
The best way to do that, you add a property to the contact object which are preseted in cells and set a value when the action method is fired. Then in cellForRowAtIndexPath: method you can set the image of the button by checking that property.
Do this
NSString *CellIdentifier = [NSString stringWithFormat:#"cell%d",indexPath.row];
While you set the default image to button also do this
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateSelected];
In your button action method do this:
-(IBAction)buttonWasPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
if(button.selected==NO) {
[button setSelected:YES];
}
}
Hope this helps.
To reuse your cell, you have to make it clean after dequeueing. In this case, you should reset your image first:
[cell.tickButton setImage:nil forState:UIControlStateNormal];
Before assigning anything to your cell.
You must save button's tag which was pressed than try this
if(pressed[cell.tickButton.tag])
[button setImage:[UIImage imageNamed:#"ticck.jpeg"] forState:UIControlStateNormal];
else
[cell.tickButton setImage:nil forState:UIControlStateNormal];
I guess you are giving the default image to your button inside the CustomCell class. This problem is very common in UITableviews.
All you need to do is keep track of the cells for which the button has been pressed. Do all this inside the cellForRowAtIndexPath method.
For example:
update the code inside cellForRowAtIndexPath method
if (cell == nil)
{
//create new cell
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(yourCondition==YES){
change the button image to the special image.
}
else{
keep the button image as default image.
}
return cell;
To keep track of the cells you can store the index path of the cells(whose button has been tapped) in an array. Inside cellForRowAtIndexPath check if the current indexPath is present inside your array or not

Strange bug in tableView

I have a UITableView, I can add and delete cell to this table. I also have two buttons. 1 button adds "1" to the cell's text, Which is 1 so basically it counts when pressing the + button and subs when pressing the - button. My problem is with the very last cell. If i add 5 cells, its the 5th cell that has the problem. If i add 200 cells its the 200th cell, etc. The problem is when i press the - button, all the other cells keep turning blue when pressed, and this button stops turning blue. It stays white when i press it when the cells text is 0. I want it to keep turning blue like all the other cells when pressed. Here is my code:
- (IBAction)subtractLabelText:(id)sender
{
cell = (UITableViewCell*)[sender superview];
if ( [[cell.textLabel text] intValue] == 0){
[newBtn setEnabled:NO];
}
else{
cell.textLabel.text = [NSString stringWithFormat:#"%d",[cell.textLabel.text
intValue] -1];
[newBtn setEnabled:YES];
}
}
This method is hooked up to the sub "-" button. Also, when i press the button when the text is = 0, the button is there but when i press it, it selects the cell and the table cell turns blue as if i selected that! Please help! Thanks everybody!
cellForRow:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.imageView.image = [imageArray objectAtIndex:indexPath.row];
cell.textLabel.text = [cells objectAtIndex:indexPath.row];
newBtn = [[UIButton alloc]init];
newBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[newBtn setFrame:CGRectMake(260,20,55,35)];
[newBtn addTarget:self action:#selector(subtractLabelText:)
forControlEvents:UIControlEventTouchUpInside];
[newBtn setTitle:#"-" forState:UIControlStateNormal];
[newBtn setEnabled:YES];
[cell addSubview:newBtn];
subBtn = [[UIButton alloc]init];
subBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[subBtn setFrame:CGRectMake(200,20,55,35)];
[subBtn addTarget:self action:#selector(addLabelText:)
forControlEvents:UIControlEventTouchUpInside];
[subBtn setTitle:#"+" forState:UIControlStateNormal];
[subBtn setEnabled:YES];
[cell addSubview:subBtn];
return cell;
}
Based on your cellForRowAtIndexPath method, you are creating and adding new buttons to each cell regardless of whether they are being reused or 'brand new'.
Your code is doing something like this:
Check if there is a cell to be dequeued/reused
If yes, grab a reference to it. If no, create a new one.
Add buttons XYZ to the cell (your mistake is here)
Return the cell for the tableview to use
Imagine that in step 2, if you a reusing an existing cell, this cell already has the buttons XYZ added to it so you are essentially adding two extra button to it when you didn't need to.
You should move the code that sets up the cell buttons to inside the if (cell == nil) loop so the buttons are only created and added to the content view if you are initialising a new cell object.
Also make sure you look at the additional comments below which are not directly related to your question but may be relevant nonetheless.
==================================================================
[EDIT - ANSWER ABOVE, BUT THIS IS ALSO RELEVANT SO I LEFT IT HERE]
This will not solve your problem, but you should be adding your buttons to the cell's contentview instead of directly to the cell, i.e.:
[cell.contentView addSubView:buttonABC];
Once that's done, you will need to call superview twice to get the cell reference in your subtract/add method:
cell = (UITableViewCell*)[[sender superview] superview];
From Apple's documentation on UITableViewCell
The content view of a UITableViewCell object is the default superview
for content displayed by the cell. If you want to customize cells by
simply adding additional views, you should add them to the content
view so they will be positioned appropriately as the cell transitions
into and out of editing mode.
At a guess, I'd say it has to do with how the UITableViewCells are being reused, in that the UI doesn't 'know' about the subview buttons on those cells.
Try commenting out the code in -cellForRowAtIndexPath that dequeues the reusable cells (so in effect you're always creating a new UITableViewCell regardless of whether cell==nil or not).
Edit:
You're referencing newBtn in -subtractLabelText, but this is an ivar that doesn't necessarily refer to the button that sent the message. Try [sender setEnabled:NO] instead.

How to identify each button in table row?

I want buttons in table row to show different titles depending on database values.
But I am facing issue in uniquely identifying each buttons i.e button 0, button 1 etc.
Note, button is in table row.
Have a look at this thread how-to-select-particular-check-box-in-tableview-which-is-inserted-in-table-cell
To uniquely identify the buttons in TAbleView you need to set the tag of each & every button
like
This this out,this will definitely solve your problem :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
UIButton *CameraBreak=[[UIButton alloc]init];
CameraBreak.frame=CGRectMake(28, 33, 60, 40);
CameraBreak.tag=indexPath.row;
[CameraBreak setImage:[UIImage imageNamed:#"Camera.png"] forState:UIControlStateNormal];
[CameraBreak addTarget:self action:#selector(CameraBtn_Clicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:CameraBreak];
//[CameraBreak release];
return cell;
}
-(IBAction)CameraBtn_Clicked:(id)sender
{
NSLog(#"%d",[sender tag]); /This will print the tag of button which you have pressed in TableView
}
Either for Dynamic Records use the Following link :
How to Select particular check Box in tableView which is inserted in table cell interface builder in iphone
Now that will work
use the NSObject property "tag" ... e.g.
UIButton* myButton;
myButton.tag = EON; OR myButton.tag = EOFF ;
if(myButton.tag == EON)
{
myButton.tag = EOFF;
//Do As per your requirement
}
else if(myButton.tag == EOFF)
{
myButton.tag = EON;
//Do As per your requirement
}
You can use table indexpath.row + your own values (0,1,2...) as tag to each button.
I m not sure but atleast you can try.

Why doesn't UITableViewCell selection not draw if I tap very quickly?

I have a a UITableView with cells that are partially custom using addSubview. I am using a different cell ID for the last cell, whose purpose is to load more data from a server which will make new cells appear. (Think the "Load more messages from server" cell in Mail.app)
E.g.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// <... code for normal cells omitted...>
static NSString *LoadMoreCellIdentifier = #"LoadMoreCellIdentifier";
UILabel *loadMoreLabel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:LoadMoreCellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
loadMoreLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.frame.size.width, self.tableView.rowHeight - 1)] autorelease];
loadMoreLabel.tag = LOAD_MORE_TAG;
loadMoreLabel.font = [UIFont boldSystemFontOfSize:16.0];
loadMoreLabel.textColor = [UIColor colorWithRed:0.153 green:0.337 blue:0.714 alpha:1.0]; // Apple's "Load More Messages" font color in Mail.app
loadMoreLabel.textAlignment = UITextAlignmentCenter;
[cell.contentView addSubview:loadMoreLabel];
}
else
{
loadMoreLabel = (UILabel *)[cell.contentView viewWithTag:LOAD_MORE_TAG];
}
loadMoreLabel.text = [NSString stringWithFormat:#"Load Next %d Hours...", _defaultHoursQuery];
return cell;
}
As you can see above, I set cell.selectionStyle = UITableViewCellSelectionStyleGray;
When you tap on a cell, I clear the selection like so:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_showLoadMoreEntriesButton && indexPath.row == [_sourceArray count])
{
// <... omitted...>
// Do a potentially blocking 1 second operation here to obtain data for more
// cells. This will potentially change the size of the _sourceArray
// NSArray that acts as the source for my UITableCell
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[self.tableView reloadData];
return;
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[self _loadDataSetAtIndex:indexPath.row];
}
The problem I'm seeing is that I have to tap and hold my finger down to have the gray highlight appear. If I tap very quickly, it doesn't display draw a highlight at all. The problem being that sometimes I perform an blocking operation that will take a second or so. I want some simple UI feedback that something is happening, instead of the UI just locking up. I think this may be related to me conditionally checking for if the indexPath is the last row of the table or not.
Any idea how to get it to draw the highlight every time?
If possible, move your blocking operation to another thread. NSOperation is probably a good system to use.
Apple's documentation
A random tutorial I found
There's no clean way to tell the UI thread to process anything while you're in the middle of a blocking operation.