Change UIButton colour and text on click in a UITableView - ios

I have to change this "Follow" Button to "Following" on clicking each cell and when I click again on "Following",it should go back to "Follow".
How is it possible?

Create action from cell to controller. now you have reference to your cell button
-(void)followButtonActionFromTableViewCell:(UIButton *)sender
{
[self followUnfolloWithButton:sender]
}
-(void)followUnfolloWithButton:(UIButton *)sender{
//you may need to call web service and set button accordingly
[sender setTitle:#"Follow" forState:UIControlStateNormal];
[sender setBackgroundColor:[UIColor yellowColor]];//set your colour
}
Use if you want reload tableview.
UIButton * button = (UIButton*)sender;
CGRect frameRect ;
NSIndexPath * indexPath ;
frameRect=[button convertRect:button.bounds toView:self.tableView];
indexPath= [self.tableView indexPathForRowAtPoint:frameRect.origin];
//Reload
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
To save state of follow/following put check condition in cellForRowAtIndexPath method. and
update your model by sender.tag
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...your code
cell.yourFollowButton.tag=indexPath.row;
//check condition and set button text and colour
}

the question is when yo click the button and change the button's some property, maybe you reload the tableView or reload cell. the status didn't cache .
the button's color and text shold obsver user model's property (eg: followStatus), when click the button , yo should change de model's followStatus and reload the cell.
thanks.

- (IBAction)btnStartOnClick:(id)sender {
UIButton *someButton = (UIButton*)sender;
NSString *str=[someButton titleForState:UIControlStateNormal];
if ([str isEqualToString:#"Follow"])
{
[btn setTitle:#"Following" forState:UIControlStateNormal];
}
else if ([str isEqualToString:#"Following"])
{
[btn setTitle:#"Follow" forState:UIControlStateNormal];
}

It's quite simple i guess. In your tableview didSelectRowAtIndexPath delegate method you just have to set your button color and title like this.
[buttonName setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[buttonName setTitle:#"Following" forState:UIControlStateNormal];
and when you click again on that same cell, you have to check button text . You can do that by setting a boolean value. i.e when you select a particular cell set boolean value to YES and set button text to "Following" and on clicking on the same cell again check if boolean is set or not if it is set you can change the text to "Follow". Other option is you have to store the selected indexpath in an mutable array and on each selection of cell try to push and pop that object in an array.. Here is other step
First create an Mutablearray in you .h File
#property (strong,nonatomic) NSMutableArray *selectedIndexPaths;
Alloc in it in your viewDidLoad method.
self.selectedIndexPaths = [[NSMutableArray alloc]init];
Add this method in you .m file
- (void)addOrRemoveSelectedIndexPath:(NSIndexPath *)indexPath
{
BOOL containsIndexPath = [self.selectedIndexPaths containsObject:indexPath];
if (containsIndexPath) {
[self.selectedIndexPaths removeObject:indexPath];
}else{
[self.selectedIndexPaths addObject:indexPath];
}}
Now in your didSelectRowAtIndexPath delegate method add this method to check if that array contains your selected indexpath.
[self addOrRemoveSelectedIndexPath:indexPath]//call of the method;
BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];
if(isSelected)
{
//change your button text and color.
}else{//unset your button text and color..}
In this way you can easily manage your indexpath of cell. regardless of getting conflict on it..

Related

Custom Cell button Click

My scenario is as follow's:
Custom Cell View
1) I am populating data from server in the custom cell view which is perfectly populated, i want a link store in my array which i want to open in browser, so i want to check which index.row button is clicked so that against that row i can get the url link and open it in browser, so far i have found the solution of button tags but that doesn't work's as well, as if we have two cell's in the screen at same time on click of button both button return's same tag.
2) As the image attached i have another storyboard in which i want to segue to a new view controller, same as mentioned above, i want to pass a specific post title and key as well.
I hope every thing is clear.
Thank's in advance.
To answer the first part of your question. Tags are a pain. It's better to pass along the UIButton as the sender, and, in the action for the button, then you can say something like:
-(void) buttonPresse:(UIButton *)sender
{
CGPoint location = [self.tableView convertPoint:sender.bounds.origin fromView:sender];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.table cellForRowAtIndexPath];
//Do what you want with the cell or indexPath
}
I have found the solution of button tags but that doesn't work's as well
Perform following steps to detect which button is selected.
Type the code snippet given below in cellForRowAtIndexPath: method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// DEFINE CELL
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// SET ACTION METHOD ON CALL BUTTON
UIButton *button = (UIButton *) [self.view viewWithTag:40];
[button setUserInteractionEnabled:YES];
[button addTarget:self action:#selector(checkButtonTapped:) forControlEvents:UIControlEventAllTouchEvents];
}
Add following method for checkButtonTapped:.
- (void)checkButtonTapped:(UIButton *)sender
{
// GET POINT OF THE BUTTON PRESSED
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
// GET INDEXPATH FOR THE CELL WHERE THE BUTTON IS PRESSED
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
//Use indxPath.row to get item
//Perform operations
}
}
There is another approach if you want to perform action according to the cell selected by the user.
For the case where you want to check which row of the cell is clicked you should use following method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"ShowindexPath%ld", (long)indexPath.row); }
Here we check for the user interaction on cell. indexPath.row will return index number for the cell selected by user. You can perform other actions in place of NSLog method.
For the purpose to send value while performing segue use following steps:
Create property in the NewViewController.h file where you want to perform segue as follow:
#property (nonatomic) NSString* receivedValue;
#synthesize property by writing following code in NewViewController.m file within #implementation and #end
#synthesize receivedValue;
ImportNewViewController.h file in TableViewController.m file.
Go to prepareForSegue: method in the TableViewController.m file from where you want to send the value and write following code according to your class names within it.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NewViewController *nVC = [segue destinationViewController];
[nVC setReceivedValue:sendValue];
}
Here sendValue is the value that you want to send.
That's all.
Build and run your project and enjoy.
You can extend UITableViewCell and add a touple property to it. key containing the index.row and value containing the URL eg:- 1:"www.stackoverflow.com". When you click on a button, all you have to figure out is the index.row and from that you can get the value that you are looking for.
you can add target for button in cellForRowAtIndexPath like :
[cell.yourButton addTarget:self action:#selector(buttonAction:event:) forControlEvents:UIControlEventTouchUpInside];
here you can receive the action for this button
-(void)buttonAction:(UIButton *)sender event:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPos = [touch locationInView:self.tblview];
NSIndexPath *indexPath = [self.tblview indexPathForRowAtPoint:touchPos];
if(indexPath != nil){
// handle click event..
}
}
surely it will work.........

Getting Picker data from a particular row

I need to get pickers value from each cell when button in that cell is clicked.Like if i click snooze button in black swan cell i should get the picker value in that cell. i am getting the row detail from
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int section = indexPath.section;
int row = indexPath.row;
NSLog(#"section: %d / row: %d", section, row);
Any help is appreciated. All the cells are custom cells.
You can get the value from the pickerssigning a tag to picker in each cell in the didSelectRowAtIndexPath like
pickerView.tag=indexPath.row;
and then in the picker delegate you can do something like following
if (pickerView.tag == 1){
//do stuff
}else (pickerView.tag == 2){
//do other stuff
}
Even you can use Switch if you want to use here too.
You can setTag to your UIButtons, with indexpath.row, if it has multi-sectioned then you can set your logic as per that, Set your UIPickerView With static Tag, which should never equal to button tag, like 999999 Tag for Pickerview.
You can set target by addTarget:action:forControlEvent method to call an instance method of the UIButton like,
//You can set it in `cellForRowAtIndexPath` method
[yourSnoozbuton addTarget:self action:#selector(selectPickerTime:) forControlEvents:UIControlEventTouchDown];
In Instance method, you can get picker value like,
-(IBAction)selectPickerTime:(UIButton *)sender {
NSIndexPath *nowIndex = [NSIndexPath indexPathForRow:sender.tag inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:nowIndex];
UIPickerView *pickerview = [cell viewWithTag:999999];
NSString *str = [timeArray objectAtIndex:[pickerview selectedRowInComponent:0]];
//if multi sectioned, get button as per logic.
}

How to Change an UIImageView Image in a Table cell, on a button click from the cell?

I created a custom table view which has custom cells,
Each cell contains an image and a button (amongst other text)
I want to be able to change the image in the UIImageView when the button is clicked,
I am able to get the click event. I however am having a difficult time changing the image.
I have attempted to get the entire cell in order to change the image using that :
UIButton *senderButton = (UIButton *)sender;
NSIndexPath *path = [NSIndexPath indexPathForRow:1 inSection:senderButton.tag];
LocationCardCell* cell = (LocationCardCell *) senderButton.superview.superview.superview;
if ([cell.class isSubclassOfClass:[LocationCardCell class]]) {
NSLog(#"cell is RIGHT CLASS!!!");
}else{
NSLog(#"cell is not THE RIGHT CLASS!!!");
}
UIView *cellContentView = (UIView *)senderButton.superview;
LocationCardCell *cell1 = (LocationCardCell *)cellContentView.superview;
if ([cell1.class isSubclassOfClass:[LocationCardCell class]]) {
NSLog(#"cell1 is RIGHT CLASS!!!");
}else{
NSLog(#"cell1 is not THE RIGHT CLASS!!!");
}
Can somebody please let me know how to go about getting the cell from the button click?
Keep this method in your arsenal...
- (NSIndexPath *)indexPathWithSubview:(UIView *)subview {
while (![subview isKindOfClass:[UITableViewCell self]] && subview) {
subview = subview.superview;
}
return [self.tableView indexPathForCell:(UITableViewCell *)subview];
}
Then,
- (IBAction)pressed:(id)sender {
NSIndexPath *path = [self indexPathWithSubview:(UIButton *)sender];
LocationCardCell* cell = (LocationCardCell *)[self.tableView cellForRowAtIndexPath:path];
// carry on happily
But not too happily. You question doesn't state what you plan to do with that cell once you have it. The generally right approach to modifying tableview cells is to modify your model, reload the cell, and then account for that change in the datasource (tableView:cellForRowAtIndexPath:).
A more conventional pattern would be to use the indexPath we just found to dereference your model, modify it, then reload.

Get a button inside tableview cell to run the same as didSelectCell

I have a tableview with a UIButton within the cell.
I have created some functionality within didSelectRowAtIndexPath. What I would like is for the same functionality/method to run when the user clicks on the button too.
How can I make the buttonPressed method run the didSelectRowAtIndexPath?
If I cannot do this, I can move the functionality to a new method and have both call this new method. However, how do I get the cell indexPath from the button pressed method?
-(IBAction)playButtonPressed:(id)sender {
NSLog(#"button pressed");
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
[self didSelectRowOrButtonAtIndexPath:indexPath];
}
I made a new method didSelectRowOrButtonAtIndexPath and called this from both the buttonPressed and the didSelectRowAtIndexPath and pass in the indexpath to be used in my method.
Find the UITableViewCell object that contains the button (must be one of its container views, just go up the superview chain).
Find the indexPath with [UITableView indexPathForCell:].
In your cellForRowAtIndexPath, assign indexPath.row to your button's tag (assuming that you only need the row - the idea is to attach the indexPath to the button somehow, tag is just one way to do it).
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
// Init / Reuse the cell ...
cell.button.tag = indexPath.row;
return cell;
}
-(void)buttonPressed:(UIButton*)button {
[self method:button.tag];
}

Hiding a Button in a UITableViewCell

I currently have a table with 8 rows that each have a label on the right side and a button on the left. I was hoping that I could have all the buttons hidden until the user presses an "edit" button in the top right corner and then they would appear allowing the user to interact with each table cell. I don't know if this is possible, because they are in UITableViewCells or if there is an easier method to summoning a button for each cell
UPDATE
okay so I have placed in all the hidden properties and there seem to be no errors, but the app doesn't recognize any of it. The buttons remains unhidden despite the fact that they are set to be initially hidden. Here is my code
Here is my Table Cell code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BlockCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = #"Free Block";
UIButton*BlockButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
BlockButton.frame = CGRectMake(225.0f, 5.0f, 75.0f, 35.0f);
[BlockButton setTitle:#"Change" forState:UIControlStateNormal];
[BlockButton addTarget:self action:#selector(Switch:) forControlEvents:UIControlEventTouchUpInside];
Blockbutton.backgroundColor = [UIColor colorWithRed:102/255.f
green:0/255.f
blue:51/255.f
alpha:255/255.f];
Blockbutton.hidden = YES;
[cell addSubview:BlockButton];
return cell;
}
and here is my method code:
- (IBAction)Editmode:(UIButton *)sender
{
Blockbutton.hidden = !Blockbutton.hidden;
[self.tableView reloadData];
}
any thoughts or ideas as to what might be the issue?
You'll need to create a UITableViewCell subclass if you don't already have one. In that class, override setEditing:animated: and if the new value is YES, then enable/add/unhide the button.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing) {
// add your button
someButton.hidden = NO;
} else {
// remove your button
someButton.hidden = YES;
}
}
It would be optional, but you are encouraged to animate the change if animated is YES.
Note: this assumes you have the edit button already hooked up the change the editing mode of the UITableView. If you don't, call setEditing:animated: on the UITableView in the button action. This will automatically call setEditing:animated: on each visible table cell.
The trick here is to keep in mind that a table's cells are determined by cellForRowAtIndexPath:. You can cause that method to be called all over again by sending the table reloadData:.
So, just keep a BOOL instance variable / property. Use the button to toggle that instance variable and to call reloadData:. If, at the time cellForRowAtIndexPath: is called, the instance variable is YES, set the button's hidden to YES; if NO, to NO.
take a BOOL variable which defines the whether to show delete button or not, use this BOOL var to for btnName.hidden = boolVar, initially make boolVar = NO, when user taps on edit toggle bool var and reload the tableview.
Another option is to test if you are in edit mode in the cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = //(obtain your cell however you like)
UIButton *button = cell.button; //(get button from cell using a property, a tag, etc.)
BOOL isEditing = self.editing //(obtain the state however you like)
button.hidden = !isEditing;
return cell;
}
And whenever you enter editing mode, reload tableView data. This will make the table view ask for the cells again, but in this case the buttons will be set not to hide.
- (void)enterEditingMode {
self.editing = YES;
[self.tableView reloadData];
}

Resources