i want to add textfield on tableview each and access the textfield's text by using their tag.
how can i do that see below image.
// To get the text from UITextField , add the bellow code to after you initialize the Textfield
[yourTextField addTarget:self action:#selector(getTextFieldValue:) forControlEvents:UIControlEventEditingDidEnd];
and this method
- (void) getTextFieldValue:(UITextField *)textField{
NSLog(#"GetTextvalue");
if (textField.tag == 0) {
NSLog(#"1--->%#",textField.text);
}else if(textField.tag == 1){
NSLog(#"2--->%#",textField.text);
}else if(textField.tag == 2){
NSLog(#"3--->%#",textField.text);
}
}
You have to customize your tableViewCell you can do that in your cellForRowAtIndexPath method.
While you create your cell in the method you can do following:
UITextField *textField = [[UITextField alloc] init];
// Set a unique tag on each text field
textField.tag = 101;
// Add general UITextAttributes if necessary
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[cell.contentView addSubview:textField];
[textField release];
After that where every you want to access your text field you can do following:
UITextField *myTextField = (UITextField*)[cell viewWithTag:yourTag];
Hope this is what you are looking for..
Update
As you can see I assigned tag 101 as static. This can be any number but make sure that you don't have any other view with the same tag in the same cell. If you have in another cell than its not an issue.
Now at anyplace if lets say in didSelectRowAtIndexPath you can do following:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UITextField *myTextField = (UITextFiled*)[cell viewWithTag:101];
This way you will get your cell first. Now your cell has only one view with 101 tag so you can get your text field regardless you have same tag for other textField because the cell is not same for all.
Cheers
UITextField *myTextField = (UITextField*)[cell viewWithTag:yourTag];
myTextField.tag=indexPath.row;
This way assign 10 textfields tags.
After in textfield delegate method you can retrieve that text from the different 10 tags.
Related
Very beginner obj-c question.
I have grouped TableView with two sections http://uaimage.com/image/c6c9ca23 . In first section I have custom cells with UITextField's in them. I need to implement Input Accessory View For keyboard with additional buttons "Next", "Prev" (to switch between text fields in first section) and "Done"(to dismiss the keyboard) http://uaimage.com/image/62f08045 .
Question is: what do I need to implement possibility to switch between text fields in cells in first section of TableView by tapping input Accessory buttons?
Do I need to tag cells or text fields and if so, how can I retrieve their value when user will tap on Input Accessory buttons? Or it is a better approach to do this?
Thanks, Alex
I assume say u have 3 UITextField ie txt ,txt1, txt 2 with tags 0 1 and 2; Now add UITableViewCell *cell in .h file.
EDIT :
Now to get references of all textField from current tableView cell add this delegate method:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
cell = nil;
cell = (UITableViewCell *)[textField superView];
return YES;
}
Now in Input Accessory prev button action do this:
-(IBAction)previousBtn:(id)sender
{
UITextField *txt = (UITextField*)[cell viewWithTag:0];
UITextField *txt1 = (UITextField*)[cell viewWithTag:1];
UITextField *txt2 = (UITextField*)[cell viewWithTag:2];
if(txt.isFirstResponder)
{
[txt resignFirstResponder];
[txt2 becomeFirstResponder];
}
else if(txt1.isFirstResponder)
{
[txt1 resignFirstResponder];
[txt becomeFirstResponder];
}
else if(txt2.isFirstResponder)
{
[txt2 resignFirstResponder];
[txt1 becomeFirstResponder];
}
}
Now in Input Accessory next button action do this:
-(IBAction)nextBtn:(id)sender
{
UITextField *txt = (UITextField*)[cell viewWithTag:0];
UITextField *txt1 = (UITextField*)[cell viewWithTag:1];
UITextField *txt2 = (UITextField*)[cell viewWithTag:2];
if(txt.isFirstResponder)
{
[txt resignFirstResponder];
[txt1 becomeFirstResponder];
}
else if(txt1.isFirstResponder)
{
[txt1 resignFirstResponder];
[txt2 becomeFirstResponder];
}
else if(txt2.isFirstResponder)
{
[txt2 resignFirstResponder];
[txt becomeFirstResponder];
}
}
In my table I use UITextField istead of UILabel (with enabled = 0).
Now pressign an add button, the last cell shall become editable. I tried the following:
UITextField *textField = [subviewsOfCell ObjectAtIndex:index];
[textField becomeFirstResponder];
but I doesn't get it editable. (I know that I get the correct cell, because textField.text = #"test"; displays correctly). What must I do?
Just try doing this:
UITextField *textField = [subviewsOfCell ObjectAtIndex:index];
textField.enabled = YES;
[textField becomeFirstResponder];
Let me know if that works for you.
when i press the new button i need to add a textfield on last row of tableview.
can any one explain the flow.
Thanks in advance.
Just i tried this scenario.
Create a one Boolean variable like this
BOOL newButtonPress = NO;
then fallow the below code
-(IBAction)newButtonClicked:(id)sender{
if (self.newButtonPress == NO) {
//if new button press then newbuttpress is yes and reload the tableview
self.newButtonPress = YES;
[self .reloadTableview reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(self.newButtonPress == YES)//creating noOfRows when newbutton pressed
{
return [self.itemNames count]+1;
}
else {
return [self.itemNames count];
}
}
Then add the below code into the cellForRowAtIndexPath method
//when new button is pressed adding new cell
if (self.newButtonPress == YES) {
if([self.itemNames count] == [indexPath row]){
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//creating the textfield if new button is pressed
UITextField *extraField = [[UITextField alloc] initWithFrame:CGRectMake(80, 6, 100, 30)];
extraField.borderStyle = UITextBorderStyleNone;
extraField.textAlignment = UITextAlignmentCenter;
[extraField becomeFirstResponder];
[extraField setDelegate:self];
[cell addSubview:extraField];
[extraField release];
}
}
If you just want the text field to appear at the end of the table, why not consider using UITableview's tableFooterView property?
In that case you don't have to ensure that you return the UITextField in your delegate methods.
You should nearly be able to drag drop a new UITextField in your Tableview if you are using InterfaceBuilder or XCode 4.
I am very new to iphone coding,i want to share my thoughts. If that is wrong please ignore.
In cellForRowAtIndexPath method u need to set a textfield in
if(indexPath.row==numberOfRows-1) condition.
In button pressed method u can set textField.hidden=NO and in viewdidload textField.hidden=YES.
I have a UITableView with a dozen rows, each containing a UITextField.
By default the UITextField contains a placeholder value "Add Value" if the user hasn't previously edited the text field:
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(158, 6, 148, 24)];
NSString *strReplacement = [valueArray objectAtIndex:indexPath.row];
if (([strReplacement length] != 0) {
textField.text = strReplacement;
} else {
textField.placeholder = #"Add Value";
}
textField.delegate = self;
[cell addSubview:textField];
[textField release];
So far so good.
I've also added a UIButton to the footer of the UITableView.
What I want is to clear all the edited values and refresh all the UITextFields in the UITableView when the user clicks the UIButton.
I can easily enough remove all objects from the valueArray but I can't figure out how to refresh all the UITableView cells to reflect the changes.
Any help is appreciated.
lq
I believe what you're looking for is
[tableView reloadData];
Your solution feels weird. Filipe's right that the correct way to do it is with [wordsTableView reloadData], which will cause tableView:cellForRowAtIndexPath: to be called for each visible cell. That method is also called as you scroll through the table, so if reloadData isn't working, you're probably also going to end up with bugs with data not updating correctly as you change it and scroll. In your clearValues method, you're doing the same thing by calling tableView:cellForRowAtIndexPath:.
I think the real problem is in your tableView:cellForRowAtIndexPath: implementation. That method generally has 2 sections. First, you create or recycle a cell to get a reference with something like:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
Inside that if statement is generally the only place you should be adding subviews to your cell. If dequeueReusableCellWithIdentifier: returns a cell, it should already have the subview.
Then, after that if statement, you populate or update the contents of the subviews. The problem with your original code is that it's populating the text field and adding it as a subview, assuming there isn't already a text field in the cell. So your tableView:cellForRowAtIndexPath: should look something more like this:
int textFieldTag = 100;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(158, 6, 148, 24)];
[textField setTag:textFieldTag];
[textField setDelegate:self];
[cell addSubview:textField];
[textField release];
}
UITextField *textField = [cell viewWithTag:textFieldTag];
NSString *strReplacement = [valueArray objectAtIndex:indexPath.row];
if (([strReplacement length] != 0) {
textField.text = strReplacement;
} else {
textField.placeholder = #"Add Value";
}
It looks like you may be setting the textField's tag value to the row number, presumably so you can use it in the UITextFieldDelegate. That could also lead to bugs, as if the cell from row 1 is recycled by dequeueReusableCellWithIdentifier: and becomes row 12, it's going to have an unexpected tag value. Even if it doesn't happen now, it's a bug waiting to happen, and will be tricky to troubleshoot.
Filipe's solution should also work, however, calling reloadData should be avoided wherever possible as calling this method has a high performance overhead.
You need some class that has a reference to both the UIButton instance as well as all the instances of the UITextField that you have on the screen/in the table. Sounds like the perfect job for your UITableView controller subclass!
In your code above, why don't you also add each UITextField that you create to an NSArray of text fields that lives in your UITableView controller? Then when the user presses the UIButton, the action can call some method in your controller class, which loops through all the UITextField elements in the NSArray setting the text property of each instance to #"".
Warning: If you're reusing cells then you may have to ensure that the controller's NSArray of UITextFields is being updated properly.
After a few hours of trial and error, I came up with this solution. The UIButton "Clear All" invokes the following method:
- (IBAction)clearValues:(id)sender {
// count the number of values in the array (this is the same as the number of rows in the table)
int count = [valueArray count];
// remove all values from the array (deletes any user added values):
[self.valueArray removeAllObjects];
UITableViewCell *cell;
UITextField *textField;
// loop through each row in the table and put nil in each UITextField:
for (NSUInteger i = 0; i < count; ++i) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
cell = [self.wordsTableView cellForRowAtIndexPath:indexPath];
// NOTE: Make sure none of your tags are set to 0 since all non-tagged objects are zero.
// In table construction, your textFieldTags should be: textField.tag=indexPath.row+1;
textField = (UITextField*)[cell viewWithTag:i+1];
textField.text = nil;
}
}
I am making an coredata application in which I was instructed to make a tableview (filling form) with textfield in each row which I did successfully. Then I made a toolbar with previous and next button and add to textField's inputAccsoryView for navigating between the textfields of each cell. One textfield per row . I am also able to do the magic with previous and next button methods . Now the problem :
Suppose I have 3 sections . In first section 4 rows . In second section 6 rows and in the last section 1 row . Now when I start from the 1st row and presses next till the 11th row it is working properly but then I press next nothing happens as the first row is dequeued I get "nil" for it . The code I am using :
configuring the cell
if (cell == nil) {
NSLog(#"tag inside:%i",tag);
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:identifier] autorelease];
UITextField *theTextField = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 170, 25)];
theTextField.textAlignment = UITextAlignmentRight;
theTextField.delegate = self;
theTextField.tag = tag;
theTextField.inputAccessoryView = [self configureTheToolBar];
[theTextField setKeyboardAppearance:UIKeyboardAppearanceAlert];
[cell.contentView addSubview:theTextField];
[theTextField release];
}
cell.textLabel.text = rowLabel;
UITextField *textField = (UITextField *)[cell.contentView viewWithTag:tag];
textField.text = rowValue
I am providing tags for textfield like 601 ,602 etc .
Then getting the currentTextField tag
- (void)textFieldDidBeginEditing:(UITextField *)textField{
currentTextField = textField.tag;
}
then the next method
if(currentTextField == 611){
currentTextField = 601;
} else{
currentTextField = currentTextField + 1;
}
NSLog(#"current text fiedld = %i",currentTextField);
NSLog(#"text ; %#",[self cellForTag:currentTextField].textLabel.text);
UITextField *firstResponderField = (UITextField *) [[self cellForTag:currentTextField].contentView viewWithTag:currentTextField];
[firstResponderField becomeFirstResponder];
and the cellForTag method :
-(UITableViewCell *)cellForTag:(NSInteger)tag{
UITableViewCell *cell;
switch (tag) {
case 601:{
NSUInteger onlyRow[] = {0, 0};
NSIndexPath *onlyRowPath = [NSIndexPath indexPathWithIndexes:onlyRow length:2];
//[self.tableView scrollToRowAtIndexPath:onlyRowPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
cell = [self.tableView cellForRowAtIndexPath:onlyRowPath];
break;
}
return cell
this code is working partially as once off screen cells get out of memory I can't reach textfield in that cell and next button stops working till the currentTextfield value reaches to any visiblerow . What could be the solution . my stack is over flowed. :)
Ok this thread does the trick but I don't know how . can anyone explain me how ?
Once a cell goes off screen it will no longer be accessible. Because of this you might want to grab the values of your text fields as soon as the user has finished editing them by wiring up the UIControlEventEditingDidEnd event:
[myTextField
addTarget:self
action:#selector(myTextChanged:)
forControlEvents:UIControlEventEditingDidEnd];
In your myTextChanged function you can store the values away, perhaps in a dictionary if you want to keep them keyed against your tags.