How to make a cell editable - ios

I am currently trying to give user the ability to edit the content of the multiple cells. Once updated, the data will be sent to web service.
Ok right now, as far as I have read, there is only "delete" and "add" row(s). I can't seem to find any guides or tutorials on how to edit the content of cell(s).
Your suggestion(s) and/or advices are much appreciated.
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}

You can not edit cell content directly. If you need to edit content then add UITextField or UITextView in cell as its subview. and then access them.
EDIT : You can add textfield as below :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// ADD YOUR TEXTFIELD HERE
UITextField *yourTf = [[UITextField alloc] initWithFrame:CGRectMake(0, 5, 330.0f, 30)];
[yourTf setBackgroundColor:[UIColor clearColor]];
yourTf.tag = 1;
yourTf.font = [UIFont fontWithName:#"Helvetica" size:15];
yourTf.textColor = [UIColor colorWithRed:61.0f/255.0f green:61.0f/255.0f blue:61.0f/255.0f alpha:1.0f];
yourTf.delegate = self;
[cell addSubview:yourTf];
}
// ACCESS YOUR TEXTFIELD BY REUSING IT
[(UITextField *)[cell viewWithTag:1] setText:#"YOUR TEXT"];
return cell;
}
Implement UITextField delegates and then you can edit cell content using this UITextField.
Hope it helps you.

Related

How to solve this override UITextField values?

I have created iOS new app. UITextField is added in each row of UITableView. first row UITextField enter values then add new row the first row UITextField values show in second row UITextField. how to solve this issues. please help me . thanks in advance.
Here is my sample code add row functionality
- (IBAction)btnAddRow:(id)sender {
[self loadData:[self.dataArray count]];
[self.tblview reloadData];
}
-(void ) loadData:(NSInteger) Indexvalue
{
newSheet = [NSDictionary dictionaryWithObjectsAndKeys:strEntryID,entryID, nil];
[self.dataArray insertObject:newSheet atIndex:Indexvalue];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UITextField *txtComment = [[UITextField alloc] initWithFrame:CGRectMake(225.0f,5.0f,50.0f,20.0f)];
[txtComment setBorderStyle:UITextBorderStyleLine];
[cell addSubview:txtComment];
[txtComment setTag:indexPath.row];
[txtComment addTarget:self action:#selector(txtCommentChange:) forControlEvents:UIControlEventEditingChanged];
return cell;
}
- (IBAction)btnAddRow:(id)sender {
[self loadData:[self.dataArray count]];
[self.tblview reloadData];
}
-(void ) loadData:(NSInteger) Indexvalue
{
newSheet = [NSDictionary dictionaryWithObjectsAndKeys:strEntryID,entryID, nil];
[self.dataArray insertObject:newSheet atIndex:Indexvalue];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
for (UIView *view in cell.subviews) {
if ([view isKindOfClass:[UITextField class]]) {
[view removeFromSuperview];
}
}
UITextField *txtComment = [[UITextField alloc] initWithFrame:CGRectMake(225.0f,5.0f,50.0f,20.0f)];
[txtComment setBorderStyle:UITextBorderStyleLine];
[cell addSubview:txtComment];
[txtComment setTag:indexPath.row];
[txtComment addTarget:self action:#selector(txtCommentChange:) forControlEvents:UIControlEventEditingChanged];
return cell;
}
You write just one for loop after your cell allocation.
txtComment.text = yourText
You missed it
You are adding a new UITextField every time that cellForRowAtIndexPath is called. Cells are re-used as you scroll, so imagine that as a cell goes off the top of the screen, its quickly taken and put at the bottom of the screen to be the new cell that is appearing. This also means that if you added a textfield first time round, then a second one will be added on top of the first.
If you add your UITextField within the same if statement where you initialize your cell, this will prevent more than one textfield appearing. Eg :
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UITextField *txtComment = [[UITextField alloc] initWithFrame:CGRectMake(225.0f,5.0f,50.0f,20.0f)];
[txtComment setBorderStyle:UITextBorderStyleLine];
[cell addSubview:txtComment];
[txtComment setTag:indexPath.row];
[txtComment addTarget:self action:#selector(txtCommentChange:) forControlEvents:UIControlEventEditingChanged];
}
Theres also a method you can use that is called when a cell is about to be recycled : -prepareForReuse. This is called on the UITableViewCell itself though, so you would need a subclass of UITableViewCell to access it.
- (void) prepareForReuse {
//set text fields to #"" for eg
}

UITableView with UISwitch

I use storyboard and Auto Layout. I add UISwitch to my cell with tag 5. When I choose first UISwitch and scroll down I see that other UISwitch is also turned on and if I scroll up my first UISwitch is turned off. How to fix this?
My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UISwitch* switchView = (UISwitch *)[cell viewWithTag:5];
[switchView addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
return cell;
}
This is because UITableView reuse UITableViewCell so one cell can be use more than once in different indexPaths, in this situation its your responsibility to maintain the state of UITableViewCell subViews. Better place to do this is cellForRowAtIndexPath where you are returning cell add logic to make show/hide UISwitch or to select accurate state i.e. on or off, you can keep that flag in dataSource object and then you can check for that flag to make set right state for UISwitch
Try This:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellSetting";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self.settingsArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if ([[self.settingsArray objectAtIndex:indexPath.row] isEqualToString:ROW_PRIVATE_BROWSING])
{
self.privateBrowsingSwitch =[[UISwitch alloc]initWithFrame:CGRectMake(cell.frame.size.width-65, 10, 30, 30)];
if (ApplicationDelegate.privateBrowsing)
{
[self.privateBrowsingSwitch setOn:YES animated:YES];
}
[self.privateBrowsingSwitch addTarget:self action:#selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:self.privateBrowsingSwitch];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Every time cellForRowAtIndexPath is called you have to replace the specific data that needs to be displayed for a cell at that position. This includes things like labels, images and your UISwitch.
This occurs because UITableViews use a small number of cells that are reused.
In cellForRowAtIndexPath add something like this:
switchView.on = [self isSwitchOnForCellAtIndexPath:indexPath]
Then write whatever logic is required to determine if the switch should be on or not.

Adding UIDatePicker to cell content view

I'm attempting to put an instance of UIDatePicker in the accessory view of a UITableView cell, and have been following this SO thread as a template. However, it looks as if the picker is being placed above the cell entirely:
Below is the code I'm using to try to add a Date Picker to the accessory view of a UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellNewRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RowCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
switch (indexPath.row) {
case EmployeeOvertimeRow:
cell.textLabel.text = NSLocalizedString(#"Test", #"One");
_datePicker = [[UIDatePicker alloc]init];
_datePicker.datePickerMode = UIDatePickerModeTime;
//OLD: cell.accessoryView = _datePicker;
//POST EDIT
[cell.contentView addSubview:_datePicker];
break;
default:
break;
}
return cell;
}
Does anyone have any guidance on what I'm doing wrong or how to fix this?
The accessoryView of a UITableViewCell is surely not what you think : it's the little view at the right of the cell, typically, it's an arrow, and it's pretty small, not made to be the width of the screen at all. You should try adding your view to the contentView. You will need to set a bigger height for your cell in the heightForRowAtIndexPath method, too.

UITextField in UITableViewCell crash

I have a text field on custom tableview cell in right half side. When I directly click on the text field am getting the keyboard. But when I clicked on the cell directly am getting the crash.
In table view didSelectRowAtIndexPath method, I have the code
[cell.txtField becomeFirstResponder];
In the console log am getting this below message:
no index path for table cell being reused
Reference crash here
IN your screen shot you are calling:
[cell.txvalue becomeFirstResponder];
Do you mean:
[cell.textField becomeFirstResponder];
?
I'm guessing cell.textValue is a string ?
As for the console log, are you calling setClearsOnInsertion property enabled on your textview ?
first of all you create configure cell as below
- (void)configureCellAcountSet:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
UITextField *txt_UserName = [[UITextField alloc] initWithFrame:CGRectMake(85, 105, 150, 25)];
txt_UserName.borderStyle = UITextBorderStyleRoundedRect;
txt_UserName.font = [UIFont systemFontOfSize:13];
txt_UserName.autocorrectionType = UITextAutocorrectionTypeNo;
txt_UserName.keyboardType = UIKeyboardTypeDefault;
txt_UserName.returnKeyType = UIReturnKeyDone;
txt_UserName.clearButtonMode = UITextFieldViewModeWhileEditing;
txt_UserName.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
txt_UserName.delegate = self;
[[cell contentView] addSubview:txt_UserName];
}
After taht confige cell use in table delegete mehode. Dont do anything didSelectRowAtIndexPath.when you click on textfield it open keyboard and click on cell nothing done there.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"section0";
tbl_setting.layer.cornerRadius = 10.0;
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[self configureCellAcountSet:cell atIndexPath:indexPath];
}
You have to implement UITextField delegate.

tableview with checkmark and detail disclosure together

I'm making a tableview with multiple row selected option. So, I used the checkmark accessory type action. I also require to edit/rename the text in the selected row.
Basically, I need to put checkmark (checkbox) on the left side and detail disclosure on the right side of the cell, both functional.
Below code is for checkmark that i have, currently checkmark appears on the right side of the cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
TSIPAppDelegate *appDelegate = (TSIPAppDelegate *)[[UIApplication sharedApplication]delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
appDelegate.selectedFile = cellText;
if (prevSP!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prevSP inSection:0]];
cell.accessoryType=UITableViewCellAccessoryNone;
prevSP=indexPath.row;
}
}
else if (prevSP!=indexPath.row){
cell.accessoryType=UITableViewCellAccessoryNone;
}
}
Any suggestions, please?
When a row selected, checkmark should be enabled/disabled AND disclosure button selected, it should open a new view for editing the selected row.
accessoryType type is of enum UITableViewCellAccessoryType, by definition it will not accept multiple values as it not bitwise enum. So, you have to choose one and mimic the other by custom code.
I'd recommend using the UITableViewCellAccessoryCheckmark accessory type on the tableview and adding a "Detail Disclosure" button to the cell. Unfortunately you can't do exactly what you're looking for, but this is the cleanest alternative approach that I've found.
This is sample code which i have used in one of my app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text=[NSString stringWithFormat:#"%#",[cellarray objectAtIndex:indexPath.row]];
cell.textLabel.textColor=[UIColor blackColor] ;
cell.textLabel.tag=indexPath.row;
cell.textLabel.font=[UIFont fontWithName:#"HelveticaNeue-Bold" size:15];
// cell.textLabel.highlightedTextColor=[UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] ;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
UIImageView *ima=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"tick.png"]];
ima.frame=CGRectMake(280, 15, 14, 14);
ima.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin;
int row = [indexPath row];
//cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
if (row==selectedRow) {
[cell.contentView addSubview:ima];
}
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Background.png"]];
[tempImageView setFrame:tableView.frame];
tableView.backgroundView = tempImageView;
[tempImageView release];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedRow = [indexPath row]; // selected row is of type int declared in .h
[tableView reloadData];
}
This code will have only one checkmark in entire tableView.. You can modify it to have multiple checkmark in that
Hope this helps !!!

Resources