I have button on uitableviewcell which have target on function like this:
likeButton?.addTarget(self, action: "likeButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
inside the function I set my button title like this:
sender.setTitle("\(addedLikeCount) Likes", forState: UIControlState.Normal)
But whenever I scroll the view up or down, my button title change to it's default. Why is that happen? Is there any way I can fix this without reloading table?
Feel free to give me any advice, doesn't matter in swift or objective c.
UPDATE
So I did code below on my function:
self.likeArray.replaceObjectAtIndex(index!, withObject: addedLikeCount)
sender.setTitle("\(self.likeArray[index!]) Likes", forState: UIControlState.Normal)
And this on my uitableviewcell:
var totalLike = likeArray[indexPath.row] as? String
currentLikeCount = totalLike
likeButton?.setTitle("\(totalLike)", forState: UIControlState.Normal)
It worked, but when I scroll the tittle become default again
Tableview cell reloads everytime it's will be shown on the screen after scroll.
You must provide reusable identifier for your cell on you storyboard or XIB
Objective-C variant:
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"your_cell_identifier_on_storyboard_or_cell_xib";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
/// datasource code here
return cell;
}
If you want to store all your context for specific indexpath, as on your question - to hold all buttons caption, use
dequeueReusableCellWithIdentifier: forIndexPath:
instead of
dequeueReusableCellWithIdentifier:
Warning: dequeuing cells for specific indexpath may slow performance
Do you use this in your code ?
tableView.dequeueReusableCellWithIdentifier("reuseIdentifer")
If yes, you have to save the state of each cell.
Because every time you scroll up and down, TableView will bring back the previous cell that outside of the screen.
What you need is setting the new state of the cell correspond to indexPath in cellForRowAtIndexPath method something like this
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifer") as? UITableViewCell{
cell.title = titles[indexPath.row]
return cell
}
...
...
}
Create a function which check for which row the title is changed and vice versa.For eg
-(BOOL)checkForSelectedRow:(NSIndexPath *)path
Now Create array which store for which button the title is changed,So whenever the button is tapped u add it to the array in your likeButtonTapped
Now in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if([self checkForSelectedRow:indexPath]){
//change the title of button
}
else{
//default of button
}
As Oyeoj commented
Cell is changing because "the cell is being reuse and therefore refreshed to its original setup under cellForRowAtIndexPath, solution is to have a global variable then setup on reload under cellForRowAtIndexPath."
For your desired task you have to store selected cell index some where i.e. your button on someIndex cell has Likes title.
for Objective-C
in .h
NSMutableArray likeArray;
in .m
in viewDidLoad
likeArray=[[NSMutableArray alloc]init];
in cellForRowAtIndexPath check
if ([likeArray containObject:[NSNumber numberWithInteger:indexPath.row]])
{
[button setTitle:#"Likes", forState: UIControlStateNormal];
}
else
{
[button setTitle:#"Some Other Title", forState: UIControlStateNormal];
}
in didSelectRowAtIndexPath -
NSNumber *cellIndex=[NSNumber numberWithInteger:indexPath.row];
if(![likeArray containObject:cellIndex])
{
[likeArray addObject:cellIndex];
}
[table reloadData];
Related
I'm just making a simple project for fun but I am having a very strange bug in my program.
This function returns 29 which is correct however it is called three times when my table view is instantiated.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
print("ingredient count: \(Sushi.ingredients.count)")
return Sushi.ingredients.count
}
And I think that (_: numberOfRowsInSection:) being called 3 times is what leads this code to execute almost three times the number of elements in the ingredients array.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
guard let cell = tableView.dequeueReusableCell(withIdentifier: "IngredientCell", for: indexPath) as? IngredientCell
else
{
return UITableViewCell(style: .default, reuseIdentifier: nil)
}
cell.ingredientLabel.text = Sushi.ingredients[indexPath.row]
print("ingredient label text: \(cell.ingredientLabel.text)\nindex path: \(indexPath)\ncell index: \(cell.index)\nbutton tag: \(cell.selectButton.tag)\nindex path row: \(indexPath.row)\ncell object: \(cell)\n")
return cell
}
The table view is populated appropriately as far as it lists all the ingredients in the array correctly. However, each row of the tableView is a prototype cell that has a UILabel, a UIButton, and a UIImage. When the button is pressed the text and color change for that button but also for every thirteenth button in the tableview cells.
This class is for my individual cells
class IngredientCell: UITableViewCell
{
public var userSelected = false
public var index: Int = 0
#IBOutlet weak var picture: UIImageView!
#IBOutlet weak var selectButton: UIButton!
#IBOutlet weak var ingredientLabel: UILabel!
//This method is called when a button is pressed
#IBAction func selectIngredient(_ sender: UIButton)
{
if userSelected == false
{
userSelected = true
selectButton.setTitleColor(.red, for: .normal)
selectButton.setTitle("Remove", for: .normal)
}
else
{
userSelected = false
selectButton.setTitle("Select", for: .normal)
selectButton.setTitleColor(.blue, for: .normal)
}
}
}
I decided to debug using print statements to see if I could figure out what exactly is going on and I found that numberOfRowsInSection is called 3 times and cellForRowAtIndexPath is called a varying amount of times. I keeps iterating over the table view giving the cell objects the same memory addresses which I suppose is what causes multiple buttons to change when only one is pressed. My console output proved that different buttons in the storyboard had the same addresses in memory.
Sorry, I can only write in Objective-C. But anyway, I am just going to show you the idea.
One of the ways to update the UI contents of just a single item of a table is to reload that specific cell.
For example: Your cell contains just a button. When you press a specific button you want to change the title of that button only. Then all you have to do is to create an dictionary which references all the titles of all buttons in your table, and then set the title to that button upon reload of that specific cell.
You can do it this way:
#interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
#property NSMutableDictionary *buttonTitlesDict;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
buttonTitles = [[NSMutableDictionary alloc] init];
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"SimpleTableItem";
UITableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(tableCell == nil)
{
tableCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
tableCell.button.title = [_buttonTitles objectForKey:#(indexPath.row)];
tableCell.button.tag = indexPath.row;
}
//reloads only a specific cell
- (IBAction)updateButton:(id)sender
{
NSInteger row = [sender tag];
[_buttonTitlesDict setObject:#"changedTitle" forKey:#(row)];
[_tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:row inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
As you can see, I just created a dictionary that holds the button title for each button with the index of the cell as the reference key. Every time I want to update the title of the button, I will get that title from the button every time the cell is loaded upon cellForRowAtIndexPath. take note that when you scroll the table, cellForRowAtIndexPath will be called when new cells appear in front of you. So as you scroll, the correct titles will be updated to the buttons.
Hope this helps.
I have a tableView with a few cells that have a black background color. On tapping the Edit Button in the navigation Bar, I would like to change the background color of area that allows re-ordering to black instead of the current white color that it shows?
I am able to change the edit button to Done using the function below but I am not sure how to change that specific area of the cells. I sense this is where I change it but i am not show how.
override func setEditing (editing:Bool, animated:Bool)
{
super.setEditing(editing,animated:animated)
if (self.editing) {
self.editButton.title = "Done"
self.navigationItem.setHidesBackButton(true, animated: true)
} else {
self.editButton.title = "Edit"
self.navigationItem.setHidesBackButton(false, animated: false)
}
}
This is the image of what I am referring to.
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
}
In this "swipe to delete" mode the table view does not display any insertion, deletion, and reordering controls. This method gives the delegate an opportunity to adjust the application's user interface to editing mode.
according to the comment you want to capture the event when user does not delete the cell but swipe to end the editing mode. For this, we have the following delegate:
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = originalColor;
}
public class MyTableSource : UITableViewSource
{
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
// abbreviation
// :
// :
cell.BackgroundColor = UIColor.Black;
return cell;
}
}
It turns out setting the cell's background color in code i.e. cellForRowAtIndexPath got the color to uniformly change to black.
I had originally done this from the UITableViewCell XIB file used.
In tableview selcting a row in didselectrow i used this
iPhone :UITableView CellAccessory Checkmark
by selecting one row i'm callling a webservice
PROBLEM : i want only one row selection not another by next time what to do
stop another rows to being selected
Add tableView.allowsSelection = false to didSelectRowAtIndexPath: and then re-set it to true at the appropriate time (I'm guessing after your web service stuff completes).
ADDED:
To make it so that the selected row cannot be selected again, I would add
Swift:
var selectedRows = [Int]()
as an instance variable (i.e. at the class level, not within a method).
Then I would change didSelectRowAtIndexPath: to something like this:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if !(selectedRows as NSArray).containsObject(indexPath.row) {
// Request data from web service because this row has not been selected before
selectedRows.append(indexPath.row) // Add indexPath.row to the selectedRows so that next time it is selected your don't request data from web service again
let cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell
cell.selectionStyle = UITableViewCellSelectionStyle.None
}
}
Objective-C:
#property (strong, nonatomic) NSMutableArray *selectedRows;
In the view controller, initialize selectedRows:
- (NSMutableArray *)selectedRows
{
if (!_selectedRows) {
_selectedRows = [[NSMutableArray alloc] init];
}
return _selectedRows;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (![self.selectedRows containsObject:indexPath.row]) {
// Request data from web service because this row has not been selected before
[self.selectedRows addObject:indexPath.row]; // Add indexPath.row to the selectedRows so that next time it is selected your don't request data from web service again
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
}
I'm having problems with table view cells not keeping their "selected" state when scrolling the table. Here is the relevant code:
#property (nonatomic, strong) NSIndexPath *selectedIndexPath;
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = indexPath;
//do other stuff
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell_iPhone* cell = [tableView dequeueReusableCellWithIdentifier:#"MyCustomCell_iPhone"];
if (cell == nil)
cell = [[[NSBundle mainBundle] loadNibNamed:#"MyCustomCell_iPhone" owner:self options:nil] objectAtIndex:0];
if ([indexPath compare: self.selectedIndexPath] == NSOrderedSame) {
[cell setSelected:YES animated:NO];
}
return cell;
}
And for the cell:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (selected) {
self.selectedBg.hidden = NO;
}else{
self.selectedBg.hidden = YES;
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
self.selectedBg.hidden = NO;
}else{
self.selectedBg.hidden = YES;
}
}
How can I get the selected cell to stay highlighted? If I scroll it off the screen, when it scrolls back on the screen it appears in its unselected state (with its selectedBg hidden).
EDIT:
Removing the setHighlighted method from the cell fixes the issue. However that means that I get no highlighted state when pressing the table cell. I'd like to know the solution to this.
Had the same problem, selected cell's accessoryView disappeared on scroll. My co-worker found pretty hack for this issue. The reason is that in iOS 7 on touchesBegan event UITableView deselects selected cell and selects touched down cell. In iOS 6 it doesnt happen and on scroll selected cell stays selected. To get same behaviour in iOS 7 try:
1) Enable multiple selection in your tableView.
2) Go to tableView delegate method didSelectRowAtIndexPath, and deselect cell touched down with code :
NSArray *selectedRows = [tableView indexPathsForSelectedRows];
for(NSIndexPath *i in selectedRows)
{
if(![i isEqual:indexPath])
{
[tableView deselectRowAtIndexPath:i animated:NO];
}
}
Fixed my problem! Hope it would be helpful, sorry for my poor English btw.
I know my method is not very orthodox but seems to work. Here is my solution:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.selected {
cell.selected = true
} else {
cell.selected = false
}
}
You must implement all the methods you mentioned on your post as well (#soleil)
I am using Xcode 9.0.1 and Swift 4.0. I found the following codes resolved my selection mark when cells off screen and back:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.isSelected {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
iOS 7/8 both deselect the cell when scrolling begins (as Alexander Larionov pointed out).
A simpler solution for me was to implement this UIScrollViewDelegate method in my ViewController:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
NSInteger theRow = [self currentRowIndex]; // my own method
NSIndexPath *theIndexPath = [NSIndexPath indexPathForRow:theRow inSection:0];
[self.myTableView selectRowAtIndexPath:theIndexPath
animated:NO
scrollPosition:UITableViewScrollPositionNone];
}
This works because my viewController is the UITableView's delegate, and UITableView inherits from UIScrollView.
If you want to achieve the same thing in Swift then here is the code. By the way I am using Xcode 7.2 with Swift 2.1.
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.selected == true{
cell.selected = true
cell.backgroundColor = UIColor.blackColor()
}else{
cell.backgroundColor = tableViewCellColor //Don't panic its my own custom color created for the table cells.
cell.selected = false
}
}
Do other customization what ever you want..
Thanks..
Hope this helped.
Swift 3 solution, 2017.
I fixed the problem with this simple line of code:
cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false
Inside the tableView(tableView:cellForRowAt indexPath:) method:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue a reusable cell
if let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID") {
cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false
// Now you can safely use cell.isSelected to configure the cell
// ...your configurations here
return cell
}
return UITableViewCell()
}
Swift 5
Put the following code in your custom UITableViewCell subclass:
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
guard !isSelected else { return }
super.setHighlighted(highlighted, animated: animated)
if highlighted {
// Style cell for highlighted
} else {
// Style cell for unhighlighted
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
// Style cell for selected
} else {
// Style cell for unselected
}
}
Explanation: Try setting breakpoints on both setHighlighted and setSelected. You'll find that the dequeueReusableCell method calls setSelected then setHighlighted in that order to reset the new cell. So your highlighting code is blowing away the styling you did in your selection code. The non-hack fix is to avoid destroying your selected styling when setHighlighted(false, animated: false) gets called.
Have you tried comparing the rows of the index paths instead of the entire index path object?
if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) {
[cell setSelected:YES animated:NO];
}
Here's the solution I came up with — and it doesn't even feel hacky.
1) Implement -scrollViewWillBeginDragging: and -scrollViewWillEndDragging:withVelocity:targetContentOffset: and manually highlight the cell for the selected row (if there is one) during scrolling.
Mine look like this:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollview {
self.scrollViewIsDragging = YES;
if( [self.tableView indexPathForSelectedRow] ) {
[[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:YES];
}
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
self.scrollViewIsDragging = NO;
if( [self.tableView indexPathForSelectedRow] ) {
[[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:NO];
}
}
The scrollViewIsDragging property is there so that in -tableView:cellForRowAtIndexPath: we can make sure any newly dequeued cells have the proper highlighting (e.g. if the cell for the selected row is scrolled onto screen after having been off screen). The pertinent part of that method looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ... cell creation/configuration ...
if( self.scrollViewIsDragging && [[tableView indexPathForSelectedRow] isEqual:indexPath]) {
[cell setHighlighted:YES animated:NO];
}
}
…and there you have it. The cell for the selectedRow will stay highlighted during scrolling.
UITableViewCell has a BOOL property "selected". Whenever you load the cell, check the state of selected and make selection or deselection accordingly as follows in cellForRowAtIndexPath definition:
if (cell.selected) {
// Maintain selected state
}
else{
// Maintain deselected state
}
Posted a quick answer to that here:
https://stackoverflow.com/a/35605984/3754003
In it, I also explain why this happens.
Do not use built-in system properties isSelected.
You can create your own property, for example:
var isSelectedStyle = false
cell.isSelectedStyle = ....
I have a question regarding uitable view.
I am implementing an app which is similar to the address book app.I am able to present the table view in editing mode. I want to let the user to edit the text in the cells in editing mode. I know that in order to edit the text in the cells, I need a textfield. I have created a textfield.
My question is:
what should I do in order to present that textfield in the cells.
what are the methods I need to implement in order to present that text field in the table view in editing mode.
Once I am done with editing ,How can I update the data which is in my contacts view controller(contains all the contacts).The saving should persist in the address book. For this question I know that I need to implement some delegate method,But I am not sure how to do that.
Please have a look at the following code,so that you will have an idea about my problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
[tableView setSeparatorColor:[UIColor clearColor]];
//[self.tableView setEditing: YES animated: YES];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
if(isEditingOn) {
if(cell == nil)
cell = [self getCellContentView:CellIdentifier];
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
UITextField *textfield1=(UITextField*)[cell viewWithTag:2];
if(indexPath.row == 0) {
lblTemp1.text = #"Name";
textfield1.text = myContact.name;
}
else if(indexPath.row == 1) {
lblTemp1.text = #"Phone";
textfield1.text = myContact.phone;
}
else if(indexPath.row == 2) {
lblTemp1.text = #"Email";
textfield1.text = myContact.email;
}
}
else {
if(indexPath.row == 0) {
cell.textLabel.text = myContact.name;
}
else if(indexPath.row == 1) {
cell.textLabel.text = myContact.phone;
}
else if(indexPath.row == 2) {
cell.textLabel.text = myContact.email;
}
}
return cell;
}
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 60, 20);
CGRect Label1Frame = CGRectMake(10, 10, 180, 25);
UILabel *lblTemp;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.tag = 1;
[cell.contentView addSubview:lblTemp];
[lblTemp release];
CGRect TextFieldFrame=CGRectMake(240, 10, 60, 25);
UITextField *textfield;
textfield=[[UITextField alloc]initWithFrame:TextFieldFrame];
textfield.tag=2;
textfield.placeholder = #"";
[cell.contentView addSubview:textfield];
}
This is a really complex question to answer this fully and in-depth with code examples, but I'll try to point you in the right direction.
1) Add a UITextField as a subview of your table cell when you create the cell in the tableView:cellForRowAtIndexPath: method (I assume that's what your getCellContentView: method is for). Set a tag on your UITextField that matches the row index of the cell and make your tableviewcontroller the delegate for the cell. Set the textfield to hidden. (remember to set the tag each time the cell is requested, not just the first time you create it).
2) In the tableView:didSelectRowAtIndexPath: method, grab the cell using tableViewCellForRowAtIndexPath and then show the textfield inside it (you may have to do some view traversal to get it) and call becomeFirstResponder on the textfield.
3) When the user has typed something, your textfielddelegate methods will be fired. You can look at the tag on the textfield to work out which row the field belongs to and then update the dat source with the new text. Then just reload the table to hide the textfield and update the cell content.
If you know how to use custom table cell subclasses then you can make your life a bit easier by creating a custom cell that already contains a textfield and has an property for accessing it, but otherwise the technique will be mostly the same.
Also, tableView:didSelectRowAtIndexPath: won't normally fire when a tableview is in edit mode unless you set tableView.allowsSelectionDuringEditing = YES;
It's better to use 2 UITableViewCells, The first one for view and the last for edit mode.
Also we will depend on the variable rowToEdit which refers to the current editing row. (in my case one cell is allowed to be edited at the same time)
let us begin:
First I depend on accessoryButtonTap action to edit the row:
var rowToEdit: IndexPath? = nil
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
// End edit mode if one cell being in edit mode other than this one
if let row = self.rowToEdit {
// return current edit cell to view mode
self.rowToEdit = nil
self.tableView.reloadRows(at: [row], with: .automatic)
}
self.rowToEdit = indexPath
self.tableView.reloadRows(at: [self.rowToEdit!], with: .automatic)
}
Differentiate between the 2 modes when you will load the cell:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath == self.rowToEdit {
let cellId = "ContactEditTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath as IndexPath) as! ContactEditTableViewCell
cell.accessoryType = .none
self.configEditCell(cell: cell, indexPath: indexPath)
return cell
} else {
let cellId = "ContactTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath as IndexPath) as! ContactTableViewCell
self.configCell(cell: cell, indexPath: indexPath)
return cell
}
}
Additional option if you want to change the height based on mode:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == self.rowToEdit {
return 120
} else {
return 70
}
}
Last option to add Save and Cancel buttons:
I added them to each cell, So I pass a reference to the ContactTable to each cell.
#IBAction func btnSave_click(_ sender: UIButton) {
// save the record
btnCancel_click(sender)
}
#IBAction func btnCancel_click(_ sender: UIButton) {
let tmp = self.tbl.rowToEdit
self.tbl.rowToEdit = nil
self.tbl.tableView.reloadRows(at: [tmp!], with: .automatic)
}