UISegmentController added to a cell - iphone

I have a tableView, and in that i have a UISegmentController. So each cell will have a UISegmentController each.
When the user clicks on a Segment in the UISegmentController (of a given cell), how do i know which cell was clicked? and i need to NSLog the title of that cell, how can i do this (note: the user will only be clicking on the UISegmentController of the cell, and not the cell it self)
The following code is the method that will be called when the UISegmentController is clicked;
-(void)segmentOfCellPressed:(id)sender{
}

Try this:
-(void)segmentOfCellPressed:(id)sender{
UISegmentController *segmentController = (UISegmentController *)sender;
YourCellClass *cell=(YourCellClass *)segmentController.superview.superview; // your clicked cell
// or a little bit more verbose but imho easier to understand:
// UIView *contentView = [segmentController superview];
// YourCellClass *cell = (YourCellClass *)[contentView superview];
NSIndexPath *path = [yourTableView indexPathForCell:cell]; //indexPath of clicked cell
}

Should be pretty easy. UISegmentedController derives from UIControl which derives UIView. UIView objects have a tag property. When you create each UISegmentedControler, give each one a unique tag value. You will need to manage which tag values separately in a dictionary perhaps.
-(void)segmentOfCellPressed:(id)sender
{
UISegmentedController *segmentedController = (UISegmentedController *)sender;
UITableViewCell *cell = [self cellFromTag:segmentedController.tag];
}
You will need to create a method called cellFromTag that will return the cell from the tag value of the UISegmentedController. If you don't want the cell but something else, then you can return that instead.

You could set the tag property of the segment controller to be the index of the cell in the cellForRowAtIndexPath then in the selector you could query the segment controller and then get the cell by the tag:
UISegmentController *segmentController = (UISegmentController*)sender;
int row = segmentController.tag;
Hopefully that helps.
In the cellForRowAtIndexPath method where you add the UISegmentController to the cell do the following:
segment.tag = indexPath.row;

Related

Determine UIButton in UITableViewCell

I have UIButton in every UITableViewCell. How can I check in which cell is button pressed?
Button is added in custom class of UITableViewCell (not in cellForRowAtIndexPath).
How it works: I have thumbUp in every UITableViewCell (grouped Tableview) and I need to know for which cell is thumbUp pressed. I can see max 2 cells at a time (because cell height is 400). I tried increment counter every time cellForRowAtIndexPath is called. It works for 1st cell but when I scroll down and cellForRow is called for second cell, counter is raised, but thumbUp button of first cell is still visible and if I press that thumbUp, it will be like 2nd cell thumbUp is pressed. Hope you understand.
Need help !!! Thanks
try this
- (IBAction)buttonWasPressed:(id)sender
{
NSIndexPath *indexPath =
[self.myTableView
indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
NSUInteger row = indexPath.row;
// Do something with row index
}
or give tag to every UIButton in cellForRowAtIndexPath method
and get cell object
- (IBAction)buttonWasPressed:(id)sender
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:sender.tag];
}

iOS: UITableView clarifications

How can I eliminate views created upon selecting a cell in UITableView when the cell is no longer selected or other cell is on selection.
Suppose I have the code below for didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize cellSize = [tableView cellForRowAtIndexPath:indexPath].frame.size;
UIView *selectionView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, (int)cellSize.width, (int)(cellSize.height + 100))];
selectionView.layer.borderWidth = 2;
[[tableView cellForRowAtIndexPath:indexPath]addSubview:selectionView];
}
Now, I want to remove that created selectionView when I focus on another cell and create it again to the cell which I am focusing.. The problem is that when I select a cell for the first time, it works perfectly but when I select another cell, the selectionView created from the previous cell still does not disappear and it duplicates the view already. How am I suppose to solve this? Need suggestion.. :( thanks..
You need to add tag for the selectionView as follows
selectionView.tag = 100;
Also , you need to have the reference of the last selected indexPath by declaring a NSIndexPath class member and retaining it.
So while selecting a new cell, get the cell with last selected indexpath and remove the view from the cell as follows
UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelIndexPath];
UIView *view = [lastCell viewWithTag:100];
[view removeFromSuperview];
You really need to look into subclassing UITableViewCell if you want a custom selection UI. Then override [UITableViewCell setSelected:animated:] (or [UITableViewCell setHighlighted:animated:]) to perform your customisations.

UITableView cells with buttons

I want to have a UIButton in each UITableViewCell that will allow me to perform selector on the object corresponding to that row. They way I got it working was to create a separate UITableViewCell for each row (no reuse), add a new UIButton that is tagged with the row. When the button gets tapped, the resulting selector checks the tag of the sender to determine which object to change.
Is there a better way of doing this? For one, I am not reusing cells which is unfortunate, and using UIView.tag seems very hacky.
You can use the same tag number on all of the UIButtons.
To extract the row number which has been clicked, implement this code in the selector:
- (void)buttonClicked:(id)sender
{
UITableViewCell * clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath * clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
int rownumber = clickedButtonPath.row;
}
I would make a subclass of UITableViewCell so that it stores a reference to a button. Then set that button when you dequeue a cell. In the method that is called, sender will be the button and you can ask for it's superview and then ask that (which is the cell) for it's index.

iphone tableview cells with custom textview - get textview reference

I have a UITableView with 15 cells, each with a separate text box in it.
I have implemented UITextViewDelegate and I am able to received changed textview data using textViewDidChange (etc). But I have one big problem still, how do I know WHICH textview sent this, (i.e. in which cell was the textview altered?)
Its interesting to have so much working, yet not know precisely where it comes from.
A whole bunch of code is available if required.
Regards #norskben
Code
// Customize the appearance of table view cells.
- (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];
//Big Text Box
UITextView *detailLabel = [[UITextView alloc] initWithFrame:CGRectMake(30, 80, CONST_Cell_width, 150)];
detailLabel.tag = 20;
[cell.contentView addSubview:detailLabel];
}
UITextView * detailLabel = (UITextView *) [cell.contentView viewWithTag:20];
You can assign tags (integers) to the different views and query the tag number to see which view called the method. Look for the tag property on the view:
tag
The receiver’s tag, an integer that you can use to identify view objects in your application.
#property(nonatomic) NSInteger tag
see here
Not at my development machine, but when you create the UITextView you should be able to assign it a tag. I think it is [myTextView setTag:x]; where x is an integer.
Then, in the TextViewDidChange use
if (textview.tag == x) {
//do something
} else if (textview.tag == y) {
//do something else and so on
}
Hope that helps a little.
The text views pass a reference to themselves in every delegate method so you know which one sent it. To make a connection to the cell, I'd set each text view's tag property to a different value that corresponds to the row of the cell they're in.
Here's an important question: Are your text boxes static, or can they change over time? If they won't change (the user can't alter the number of cells or add more later), then you can declare a new textField for each cell. I have something similar in my apps. I have two text boxes, and depending on which textField is currently active, the delegate does something different.
Declare separate text fields in your header
UITextField *textField1;
UITextField *textField2;
UITextField *textField3;
in the delegate method, use if statement blocks to find out which textField is changing:
if (textField == textField1) {
//do something
} else if (textField == myTextField2) {
//something else
}
Note that this really only works if your view is static.
Hope this helps
Have a great day
When you're searching the UITableView's cells for the event source UITextView, only iterate over the cells that the user can currently see. This can be obtained using the following UITableView method:
- (NSArray *)visibleCells

UITableView Custom Cell Resets Cell Content

Okay I know I'm running up against my limits of understanding as regards objective-c, cocoa, xcode, and blah blah and so on. But here's what I'm trying to do:
I have a tableview in a viewcontroller. The tableview's delegate is the viewcontroller. Viewcontroller has an outlet to the tableview. The table is put together using custom cells (with IB xib) and data from an xml file. In the custom cell there are two buttons - and when the cell is created the button action is added as an addTarget to self (the viewcontroller) which then goes to an action. The viewcontroller button action method gets the row of the button pressed in the table and then changes the cell's text and the button's title.
But of course when I scroll that particular cell out of view and back into view it's been reset to the beginning state. I assume this has to do with cell dequeueing etc. Any ideas?
here's the relevant bits and code:
custom cell: has outlets to buttons and textlabel.
cell create code in the datasource cellForRowAtIndexPath...
{
static NSString *dialogueCellIdentifier = #"dialogueCellIdentifier";
dialogue_cell *cell = (dialogue_cell *)[tableView dequeueReusableCellWithIdentifier:dialogueCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"dialogue_cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
[[cell lButton] addTarget:self action:#selector(lButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
[[cell lButton] setTag:[indexPath row]];
NSString *row = [NSString stringWithFormat:#"%i",[indexPath row]];
NSString *en = [[self.dataArray objectForKey:row] valueForKey:#"en"];
cell.mainText.text = en;
return cell;
}
and the lButton method...
NSIndexPath *thisCellPath = [NSIndexPath indexPathForRow:[sender tag] inSection:0];
dialogue_cell *thisCell = (dialogue_cell *)[self.dialogueTable cellForRowAtIndexPath:thisCellPath];
NSString *row = [NSString stringWithFormat:#"%i",[sender tag]];
if ([thisCell.languageButton.currentTitle isEqualToString:#"en"]) {
[thisCell.languageButton setTitle:#"zc" forState:UIControlStateNormal];
thisCell.mainText.text = [[self.lineArray objectForKey:row] valueForKey:#"lineText_zc"];
} else {
[thisCell.languageButton setTitle:#"en" forState:UIControlStateNormal];
thisCell.mainText.text = [[self.lineArray objectForKey:row] valueForKey:#"lineText_en"];
}
so two questions:
1. is there a way to make the cell retain what is in the label and button name even though it's scrolled offscreen?
2. is there a way to set the label and button name within the cell custom class instead of sending the button action to the viewcontroller that the table is in?
Thanks!
It does not really have anything to do with the dequeueing of cells but the data you are displaying in the cellForRowAtIndexPath. Every time a cell is going to be displayed, this method is called.
I assume you are changing the language of the cell's text on button click. But every time the cell is redrawn you are redisplaying the english text. One way to "retain" the cell's state would be to create an array for the languages being used on each cell and based on the array's value for a particular row, populate the cell's text. You will just have to maintain the state of the cell in the array.
OK i had this problem too, took me awihle but I figure it out, the cell queue is they key here, when you are trying to get your cell back your are using this
NSIndexPath *thisCellPath = [NSIndexPath indexPathForRow:[sender tag] inSection:0];
dialogue_cell *thisCell = (dialogue_cell *)[self.dialogueTable cellForRowAtIndexPath:thisCellPath];
When the cell is off the view, the table view unloads this cell and instead you get a cell thats in the original state (or prolly nil) when you call this because its n ot longer part of the table view until the cells come back into the view screen.
What you have to do is since you a re enqueuing your cells, I am going to assume you are doing this correctly and you are giving a different name to each cell, instead of doing what you did above you must get your cell like so
cell=[tableView dequeueReusableCellWithIdentifier:dialogueCellIdentifier];
This will give you your cell with the state it was in when the user modified it...Hope this helps!
As for your second question, you can just set the target to be the cell instead of the view controller, this will call that action inside your custom cells class..