UITableview Insert/Delete - ios

I am having one number of section base tableview in that plus button which will add new item in tableview.
While i try add or delete the section from tableview and reload that tableview it will blink old record many times and then add or delete the section. Here is the code.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SymbolTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectIndexPath containsObject:[NSNumber numberWithInt:(int)indexPath.section]])
{
[selectSymbol removeObject:cell.lblsymbol.text];
[selectIndexPath removeObject:[NSNumber numberWithInt:(int)indexPath.section]];
}
else
{
NSString *strr = cell.lblsymbol.text;
[selectSymbol addObject:strr];
[selectIndexPath addObject:[NSNumber numberWithInt:(int)indexPath.section]];
}
[tblDetail reloadData];
}
what is the issue?

try following code it may helps you
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
SymbolTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectIndexPath containsObject:[NSNumber numberWithInt:(int)indexPath.section]])
{
[tblDetail beginUpdates];
[selectSymbol removeObject:cell.lblsymbol.text];
[selectIndexPath removeObject:[NSNumber numberWithInt:(int)indexPath.section]];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
else
{
NSString *strr = cell.lblsymbol.text;
[tblDetail beginUpdates];
[selectSymbol addObject:strr];
[selectIndexPath addObject:[NSNumber numberWithInt:(int)indexPath.section]];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}

You can reload cell which you removed/added
You will not reload all table.
Try the following code please
[self.tableView deleteRowsAtIndexPaths:#[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];
or
[self.tableView insertRowsAtIndexPaths:#[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];

for inserting row in tableview
- (void)insertNewObject:(id)sender
{
if (!arrayForTableContent) {
arrayForTableContent = [[NSMutableArray alloc] init];
}
NSInteger count = [arrayForTableContent count];
NSString *strTobeAdded = [NSString stringWithFormat:#"%d",count+1];
[arrayForTableContent insertObject:strTobeAdded atIndex:count];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:count inSection:0];
[self.tableViewForScreen insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

I'm not writing all the code nor test it in the debugger, but I will give you an advice of how to proper implement this. Let's say you have a datasource, like this:
NSMutableArray *data = #[#"First", #"Second", #"Third"];
Datasource: In numberOfRowsInSection, you return data.count; in cellForRowAtIndexPath, you will configure the cell with the respective index from the array;
Delegate: In didSelectRowAtIndexPath, remove the object from the data array, say you will need something like this: [data removeObjectAtIndex(indexPath.row)]; then call reloadData on the table view. The table view will smoothly return now just two items.

Related

Attempt to create two animations for cell

I would like to create cell by expand and collapse. To do this i animate the cell by reloading. When i expand it works fine. But when i collapse it crashes and the reason is Attempt to create two animations for cell. I know Ive given same array paths and it wont reload two cell at the time. Is there a way to fix this.
I am new to coding, so i would be happy to get a simple solution.
Code:
The reason am using lastSelIPath is when first cell is expanded and touch the second cell the first cell would collapse and the second cell would expand.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath* lastSelIPath = [ NSIndexPath indexPathForRow:selectedIndex_ inSection:0 ];
[ tableView deselectRowAtIndexPath:indexPath animated:YES ];
if (selectedIndex_ == indexPath.row)
{
selectedIndex_ = -1;
}
else
{
selectedIndex_ = indexPath.row;
}
NSIndexPath* ipath = [ NSIndexPath indexPathForRow:indexPath.row inSection:0 ];
NSArray* indexPathArr = [ NSArray arrayWithObjects:lastSelIPath, ipath, nil ];
[ tableView beginUpdates ];
[ tableView reloadRowsAtIndexPaths:indexPathArr withRowAnimation:UITableViewRowAnimationAutomatic ];
[ tableView endUpdates ];
}
So what i did now I set a condition and reload the one i wanted. Is it a correct method to follow please help.
Modified code:
if ( lastSelIPath.row == ipath.row )
{
[tableView reloadRowsAtIndexPaths:#[ipath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else
{
[tableView reloadRowsAtIndexPaths:#[lastSelIPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadRowsAtIndexPaths:#[ipath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Crash is right, you are trying to attempt two animation. Your indexPathArr contains two objects. Do not create this array and try this:
[tableView reloadRowsAtIndexPaths:#[lastSelIPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadRowsAtIndexPaths:#[ipath] withRowAnimation:UITableViewRowAnimationAutomatic];
Let me know, if it helps
[tableView reloadRowsAtIndexPaths:#[newIndexPath, oldIndexPath] withRowAnimation:UITableViewRowAnimationNone];
If newIndexPath is same as oldIndexPath, it will crash in iOS8, but this is fixed in iOS9 and later.
You can use third party library for expanding cell.
https://github.com/bennyguitar/CollapseClick
& implement there delegate method as
-(int)numberOfCellsForCollapseClick
{
}
-(NSString *)titleForCollapseClickAtIndex:(int)index {
}
-(UIView *)viewForCollapseClickContentViewAtIndex:(int)index {
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedTag==1) {
selectedIndex=indexPath.row;
[self performSelector:#selector(Write Your Action) withObject:nil];
}
NSMutableArray *modifiedRows = [NSMutableArray array];
if ([indexPath isEqual:self.expandedIndexPath]) {
[modifiedRows addObject:self.expandedIndexPath];
self.expandedIndexPath = nil;
}
else {
if (self.expandedIndexPath)
[modifiedRows addObject:self.expandedIndexPath];
self.expandedIndexPath = indexPath;
[modifiedRows addObject:indexPath];
}
// This will animate updating the row sizes
[tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];
// Preserve the deselection animation (if desired)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Using Selected Tag write the condition of your cell expand action. may be it helps.

insertRowsAtIndexPaths or reloadData doesn't respond

Here is my code. And yesterday it works just fine. But this morning, it doesn't work.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
RSDrug *drug = [[RSDrug alloc]init];
[drugArray insertObject:drug atIndex:0];
NSIndexPath *ip = [NSIndexPath indexPathForRow:1 inSection:0];
[tableView insertRowsAtIndexPaths:#[ip] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return drugArray.count + 1;
}
I have tried to add some code like beginUpdates/endUpdates, or I delete insertRowsAtIndexPaths, just use reloadData.
But same result. When the app runs to insertRowsAtIndexPaths or reloadData, it stuck, no response.
So I need some help. How to solve this?
Found the problem..........A stupid mistake
There are two UITextFields in the added cell, and they all have the same leftView, my code is like this:
UIImageView *leftImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"img"]];
field_1.leftView = leftImage;
field_2.leftView = leftImage;
I never know that I can't reuse the leftView. If I set the leftImage to field1, I can't set it to field2 anymore.
When I changed to this, it works again.
field_1.leftView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"img"]];
field_2.leftView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"img"]];
Try this sequence...
NSMutableArray *indexPaths=[[NSMutableArray alloc]init];
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView beginUpdates];
RSDrug *drug = [[RSDrug alloc]init];
[drugArray insertObject:drug atIndex:0];
if (indexPath.row == 0) {
[indexPaths removeAllObjects];
[indexPaths addObject:[NSIndexPath indexPathForRow:indexPath.row++ inSection:0]]; // here inserting row index=1;
[tableViewMenuList insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
[tableView endUpdates];
}
Have you tried this?
RSDrug *drug = [[RSDrug alloc]init];
[drugArray insertObject:drug atIndex:0];
[tableView beginUpdates];
// indexpath inserted is with the index 0 same with the `insertObject: `
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView insertRowsAtIndexPaths:#[ip] withRowAnimation:UITableViewRowAnimationAutomatic];
//here is what i use to do instead of #[]
//[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
EDIT
Your code are working fine. i tested it. here..
Code:
Output:
Log:
Check the tested code above if you have omitted something.
I think the problem is the delegates of your table, make sure that your table have the delegate for both UITableViewDataSource & UITableViewDelegate.
Hope this is helpful.. Cheers.. :)

UITableView insert row at top crashes

I'm trying to insert a row at the top of UITableView, but it crashes in the last line where I declare the endUpdating. This is the code I'm using and I'm using a button outside the table to insert row.
[comments insertObject:comment atIndex:0];
[self.commentsTableView beginUpdates];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates]; //here crashes with "assertion failure"
I know I can just do insert in array and reload, but I want to do it with animation.
Thank you in advance.
This is my cell for row method
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CommentCell";
// Similar to UITableViewCell, but
ListingCommentTableViewCell *cell = (ListingCommentTableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[ListingCommentTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.commenterLabel.text = [[comments objectAtIndex:indexPath.row] objectForKey:#"user"];
[cell.commenterLabel sizeToFit];
cell.commentLabel.text = [[comments objectAtIndex:indexPath.row] objectForKey:#"text"];
[cell.commentLabel sizeToFit];
cell.lineView.frame = CGRectMake(5 , cell.commentLabel.frame.origin.y + cell.commentLabel.frame.size.height+ 5, cell.frame.size.width-20, 1);
cell.dateLabel.text = [Utils formatCommentDate:[[comments objectAtIndex:indexPath.row] objectForKey:#"createdOn"]];
return cell;
}
THis is my cell height method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int height = [Utils findHeightForText:[[comments objectAtIndex:indexPath.row] objectForKey:#"teksti"] havingWidth:screenWidth - 40 andFont:[UIFont fontWithName:#"Ubuntu" size:14]];
height += 25;
return height + 5;
}
and my number of rows method
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
return [comments count];
}
This is how I insert objects to UITableView with animation.
-(void)updateMethod {
[self.commentsTableView beginUpdates];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:0];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[comments insertObjects:[NSArray arrayWithObjects:comment, nil] atIndexes:indexSet];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates];
}
You should check numberOfRowsInSection and be sure it reflect your comments.count
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return comments.count;
}
Also all UI updates must be done on the main thread, if you call your update method in different thread there is a change you can see that error.
You should update data source array inside animation block:
[self.commentsTableView beginUpdates];
[comments insertObject:comment atIndex:0];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.commentsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.commentsTableView endUpdates];

UITableView cell not deleting

Basically I have an app where you can swipe a tablecell off the screen and it "deletes" the cell. My delete method is called by this: (this happens when the cell reaches a certain point on the phone)
[tableCellTrash addObject: [NSIndexPath indexPathForRow:[numbers indexOfObject:[aPanGestureRecognizer view]] inSection:0]];
UITableViewCell *cell = [numbers objectAtIndex:[numbers indexOfObject:[aPanGestureRecognizer view]]];
[self deleteCell: cell];
This is the delete cell method
-(void)deleteCell: (UITableViewCell *) cell{
[self.tableView beginUpdates];
[numbers removeObject:cell];
[self.tableView deleteRowsAtIndexPaths:tableCellTrash withRowAnimation:UITableViewRowAnimationFade];
[tableCellTrash removeObjectAtIndex:0];
[self.tableView endUpdates];
//[self.tableView reloadData];
}
I have no idea what's wrong, the cell doesn't delete. Any help would be appreciated.
tableviews have a delegate method to handle the event for delete:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
[tableView reloadData];
}

Add cell/data to the top of UITableView

I'm trying to create a simple chat application for iOS. It currently looks like this:
I want to change the order that the messages is displayed, i.e. display the latest message over the older messages. My current implementation looks like this:
// Datasource for the tableView
messages = [[NSMutableArray alloc] init];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[...]
// messageTextView is a contentView subView.
messageTextView.text = [messages objectAtIndex:indexPath.row];
[...]
- (IBAction)sendMessage:(id)sender
{
[messages addObject:messageField.text];
messageField.text = #"";
[self.tableView reloadData];
/*
I have tried the implementation below, but I always got an exception.
[self.tableView beginUpdates];
NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSArray * indexArray = [NSArray arrayWithObjects:path1,nil];
[self.tableView insertRowsAtIndexPaths:indexArray
withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
*/
}
Any tips on how to do this would be great.
Thanks.
Simple you need to insert the new UITableViewCell at the 0 index. Also modify your Datasource otherwise your app will crash. Below I show how to modify your UITableView. Modifying your datasource is easy.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
What you are essentially doing here is inserting the new chat message cell at the 0th index position. You could use a nice animation effect to make it appear or fade in.
There are various animations that you can use here-
UITableViewRowAnimationBottom
UITableViewRowAnimationFade
UITableViewRowAnimationMiddle
UITableViewRowAnimationNone
UITableViewRowAnimationRight
UITableViewRowAnimationTop
You can try.
[messages insertObject:messageField.text atIndex:0];
instead of [messages addObject:messageField.text];.
Swift Solution
Define array like this
var arrMessage = [AnyObject]()
and Button Action
#IBAction func btnSendMessageTapped(sender: AnyObject) {
arrMessage.insert(txtTypeMessage.text!, atIndex: 0)
txtTypeMessage.text = ""
self.tblMessage.reloadData()
}

Resources