I have table view with UIButton , UILable and UITextfield
I have wrote in cellForRowAtIndexPath:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell addSubview:button];
[cell addSubview:lable];
[cell addSubview:textfield];
I have set the text on lable and textfield are working properly.
When i change the text on textfield are also working properly.
And i have other button for save data - it's a out side of tableview but in the same view.
My Question is when i click save button i want to get text of tableview's textfield.
If you have one or two textfields create it in the IB but outside the currentview, hook to outlet, then use the outlet to save the text .this is not a good idea if your table view containing many rows, in that case consider creating custom cell
Check this answer
Do you want the text in every text field or a single row's?
Also, the code you use to create your table view cells isn't doing what you want it to do. First you are trying to dequeue a reusable cell, which is great. But you then immediately overwrite that reused cell by alloc/initing a brand new cell every time. Only if cell == nil should you alloc/init a new one.
All of the textFields? I would recommend adding the textFields to a mutableArray as they are created, creating another mutableArray to store the textField text, then on button push, calling:
for(UITextField *textField in myArray){ [myTextArray addObject:textField.text];}
Then you could save the array, or whatever. If there's only one textField, how you access it will depend where it's declared, etc.
Related
e.g as you are watching the tableView having cell with plus Button, when I press that button it hides the current button but when I scroll the tableview Some other button on other customCells are also get hide but I didn't hide them. please help me out. How to fit this problem.
The UITableView is caching the cells, which means it doesn't store all cells at all time, which is brilliant in terms of memory. The problem with it, that it has no reference to the value stored in that cell when the cell is reused. What is often done, is that all values stored in a dynamic cell is stored in separate NSMutableArrays.
For your problem, you could add an array with the boolean values indicating whether they are hidden or not, and read from that in the tableView:cellForRowAtIndexPath: delegate method with
cell.hidden = [[self.yourArray objectAtIndex:indexPath.row] boolValue];
And in the button callback method you should change the hiddenproperty as well as updating the value in the array.
i'll do it as follow:
first you have to track the button's state:
Shown
or
Hidden
this is done by holding the state in an NSMutableArray
in the viewDidLoad method add the following
NSMutableArray *shownButtons = [[NSMutableArray alloc] init];
then in your tableView:cellForRowAtIndexPath do the following
NSString *tmpIndexPathString = [NSString stringWithFormat:#"%d",indexPath.row];
if ([shownButtons containsObject:tmpIndexPathString])
{
[cell.myButton setHidden:YES];
}
else
{
[cell.myButton setHidden:NO];
}
In the tableView:cellForRowAtIndexPath: delegate method you need to loop through all the visible cells:
for (UITableViewCell *cell in [self.tableView visibleCells]) {
// now you have a cell that you can update
}
You also have to remember to update your data source so scrolling the table will update the cells accordingly and not show the plus button. If you're updating your data source what you can do is reload the cell in the above for loop for example.
I am trying to make an app that will display a bunch of different people's names and address in different cells of a UITableView. First I'm just trying to get the hand of adding text to the cells, and it's not really working. I have the following code, where myTableViewController is just a subclass of UITableViewController that loads in its view from a nib (without any drastic customizations):
myTableViewController * tvc = [[myTableViewController alloc] initWithStyle:UITableViewStylePlain];
NSIndexPath *path1 =[NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *path2 =[NSIndexPath indexPathForRow:1 inSection:0];
[self presentModalViewController:tvc animated:YES];
UITableViewCell * cell1 = [tvc.tableView cellForRowAtIndexPath:path1];
UITableViewCell * cell2 = [tvc.tableView cellForRowAtIndexPath:path2];
cell1.textLabel.text = #"test";
cell2.textLabel.text = #"test2";
I was expecting to see a tableView animate onto the screen, followed by the first and second cells being filled with the text "test" and "test2" respectively. What I get is a blank tableview animating onto the screen. Then if I scroll down so that the top cell is hidden and scroll back up so that the top cell is again visible, the top cell will now have the text "test" in it. But the second cell down never shows any text, just the top one.
Can someone please point me in the right direction? I also would like to have the text in the tableview BEFORE it loads onto the screen, but it looks like the cells don't exist unless they are being displayed. Please help me.
Populating a table view takes the form of a data-source pattern, where the table view calls your data source object for data to put in individual cells.
Try reading through the Table View Programming Guide.
You should use the delegate and the datasource protocol methods.
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.
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
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..