Getting Picker data from a particular row - ios

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.
}

Related

How to differenciate indexPath of first cell with indexPath of empty space at the end of table?

I use the following code to detect a click on a UITableView and take action depending on which cell is clicked, and which element in the cell was clicked, with a default action for any element that doesn't match.
-(void)addTapRecognizer {
// this is called when the view is created
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
singleTap.delegate = self;
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.tableView addGestureRecognizer:singleTap];
}
- (void)handleTap:(UITapGestureRecognizer *)tap {
NSLog(#"tap detected!");
if (UIGestureRecognizerStateEnded != tap.state) {
return;
}
UITableView *tableView = (UITableView *)tap.view;
CGPoint p = [tap locationInView:tap.view];
NSIndexPath* indexPath = [tableView indexPathForRowAtPoint:p];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(#"selectedIndex = %ld", (long)indexPath.row);
// take action depending where the cell was clicked
// with a default action if no element matches
MyTableViewCell *cell = (MyTableViewCell *) [self.tableView cellForRowAtIndexPath:indexPath];
CGPoint pointInCell = [tap locationInView:cell];
if(CGRectContainsPoint(cell.someImage.frame,pointInCell)) {
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
if (...) {
...
return;
}
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
My problem is that when there aren't enough cells to fill the screen (so for instance the table contains 2 cells and then blank space below), when the user clicks below the last cell, this is treated as a click on the first cell (the console logs "selectedIndex = 0" in both cases).
Is there a way to tell the difference between such a click, in the empty space at the end of the table, and a click on a "proper" cell of the table?
Is there a way to tell the difference between such a click, in the empty space at the end of the table, and a click on a "proper" cell of the table?
Yes. For the cheap and easy solution only do what you are trying to do if you actually get an indexPath:
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:p];
if(indexPath != nil){
// do everything in here
}
Basically, your indexPath is returning nil because it can't find a row. From the docs:
An index path representing the row and section associated with point, or nil if the point is out of the bounds of any row.
You could do it the way that you're currently doing it but is there any reason why you aren't using:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This is a much more standard way of detecting the cell that the user tapped on.
This method won't be called if you tap on something that isn't a cell and has a number of other benefits. Firstly you get a reference to the tableView and the indexPath for free. But you also won't need any gesture recognisers this way either.
Try something like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// Do stuff with cell here...
}
Obviously this all assumes that you have correctly set a class as your table view's delegate.
NB: It's very easy to mistakenly write didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath when using Xcode's autocompletion to do this. I always do this and then inevitably realise my mistake 20 minutes later.

Enabling UIButton in TableViewCell enables in more Cells

I have a TableViewController with my customed TableViewCell, on each row there are two buttons, one is hidden the other is not, when I tap the shown button I want to show the other button, I´ve covered this, my problem is, if I scroll down other hidden buttons are showed because of the Reuseidentifier.
What can I do to only show up the button from the row I`ve selected.
Hope I got clear if not please ask me.
Thank you all.
When you scroll the tableView remaining buttons are hidden because you wrote setHidden method in cellForRowAtIndexPath Without putting any condition so take one NSMutableArray and allocate memory to it. Whatever the index you select just add it MutableArray.Then in cellForRowAtIndexPath Put one condition if that array contains the indexPath don't hide else hide the button.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CutomTableView *cell=[tableView dequeueReusableCellWithIdentifier:#"CellId" forIndexPath:indexPath];
[cell.show setTag:indexPath.row];
[cell.show addTarget:self action:#selector(showButtonACtion:) forControlEvents:UIControlEventTouchUpInside];
NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
//self.selectedRow is NSMutable Array
if ([self.selectedRow containsObject:selectedIndexPath]) {
[cell.hideBtn setHidden:NO];
}else{
[cell.hideBtn setHidden:YES];
}
return cell;
}
-(void)showButtonACtion:(UIButton*)sender{
NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
[self.selectedRow addObject:myIP];
[self.tableV reloadData];
}
When you click on particular button to show another button, just save that NSIndexpath.
For example,
If you are click on 2nd row, then add value in NSMutableDicionary as
[mutableDict setValue:#"YES" forKey:[NSString stringWithFormat:#"%#", indexPath.row]];
And then check for particular indexPath in cellForRowAtIndexPath method.
Whenever you find #"YES" for particular row, implement your desired logic to show or hide buttons.
Hope this helps you.
-(IBAction)firstButton:(UIControl *)sender
{
UIButton *button = (UIButton*)sender;
NSIndexPath *myIP = [NSIndexPath indexPathForRow:sender.tag inSection:0];
CustomCell *cell = (CustomCell*)[self.tableView cellForRowAtIndexPath:myIP];
[cell.button2 setHidden:NO];.
}

Change UIButton colour and text on click in a UITableView

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..

TableViewCell should not get reuse

I am using UITableview in my project, and also i have UITableviewcell for that UITableview. The problem is that cells are getting reused.if it get reused, when i select button i want the image to be changed for single cell and button isSelected =YES. So the button's selected image is getting reuse for every cell.
So,kindly help me out with this problem .
// In indexPathRow before return
cell button.tag=indexPath.row;
In buttonclick action
//
-(IBAction)BtnAction:(UIControl *)sender
{
UIButton *button = (UIButton*)sender;
NSIndexPath *buttonIP = [NSIndexPath indexPathForRow:sender.tag];
//Type cast it to CustomCell
CustomCell *cell = (CustomCell*)[table cellForRowAtIndexPath:buttonIP];
if(button.isSelected==NO)
{
cell.Imageview.image=selectedImage;
button.isSelected=YES;
}
else
{
cell.Imageview.image=OldImage;
button.isSelected=NO;
}
[table reloaddata];
}
insted of using the above code you can use this line of code
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(firstTime)
{
[tableView cellForRowAtIndexPath:indexPath].imageView.image = [UIImage imageNamed:#"selected image"];
[attatancearry addObject:value];
}
if(secondTime)
{
[tableView cellForRowAtIndexPath:indexPath].imageView.image = [UIImage imageNamed:#"absent image"];
[attatancearry removeObject:value];
}
}
and add the value to an another nsmutablearry as the attendence is added and when you press the same cell again you have to remove the value from the nsmutablearray you have added before, and reset the image back to absent. but you don't have to reload the entire tableview it will just change the cell which you have select right now. as your adding the value or index number of the cell into a array you can use the selection value for further use.
you have to see the cell which you have selected, and set a flag value as the selected index. and reload the table.
when you reload the table check the flag value and set the image which you want to set for the cell which is selected. it will give you different cell selection.
for example
int selectionFlag = -888;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectionFlag == indexPath.row)
{
//set the image you want to set for the cell which is selected.
}
else
{
//the normal image you want to set.
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectionFlag = indexPath.row;
[tableView realoadData];
}

iOS how to get, current selected indexpath row on cellForRowAtIndexPath method?

I want to make a link using label in every cell of table.
When the link is clicked, the table will get the [indexpath row] of the cell and we will use the index to match with the array index containing string data. The string will be sent to the next push page.
I'm using UITapGestureRecognizer to tap the label and put parameter to selector method.
How to get the current indexpath row the label on the selected cell?
This is my sample code :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
UITapGestureRecognizer *gestureRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(openUrl:) ];
gestureRec.numberOfTouchesRequired = 1;
gestureRec.numberOfTapsRequired = 1;
[cell.listPrice addGestureRecognizer:gestureRec];
[gestureRec release];
...
}
- (void)openUrl:(id)sender
{
NSLog(#"DOwnload URL send >> %#",urlDownloadSend);
DownloadNowController *download =[[DownloadNowController alloc]initWithNibName:#"DownloadNowController" bundle:nil];
[self.navigationController pushViewController:download animated:YES];
[download release];
}
To determine the current selected cell you can use next method of UITableView:
- (NSIndexPath *)indexPathForSelectedRow
But I'm not sure that your cell will be selected after UITapGestureRecognizer fired.
I advice you to store row of the cell directly in gestureRec.view in tag property:
gestureRec.view.tag = indexPath.row;
Then in openUrl you can determine the selected cell by getting value of sender.view.tag
It is not very clear what you want to do.. do you have a link layed out on the UITableViewCell which triggers some other actions?
The UITableViewDelegate gives you some really cool methods called:
– tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:
When you tap a cell, the willSelectRowAtIndexPath and didSelectRowAtIndexPath are called - supplying you the currently selected NSIndexPath which you can then use to get the row as follows:
indexPath.row;
You can use a global variable to keep the value of indexpath.row
store the row in didSelectRow:atIndexPath: method
var = indexPath.row;
[tableView reloadData];
var = indexPath.row;
[tableView reloadData];
then use it in cellForRowAtIndexPath
if(indexPath.row==var){
}
You may implement method – tableView:willSelectRowAtIndexPath: in your UITableViewDelegate. There you can easily obtain information on indexPath.
you can do like this
in cellForRowAtIndexPath data source method
UIImageView* selectedBg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"bg_selected.png"]];
cell.backgroundView = [[UIView alloc] initWithFrame: CGRectZero];
cell.selectedBackgroundView = selectedBg;
[cell.backgroundView setNeedsDisplay];
[selectedBg release];
The following code can be used to obtain the current selected indexpath row:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
NSLog(#"selected tableview row is %ld",(long)indexPath.row);
}

Resources