In my iOS app I am using Core Data to show data on a table view this is working fine .
what i want to do is :
when clicking on the navigation back button of view controller i want
to delete tableview cell if the textview on the View controller is empty .
i want to do it like Apple note app .
can any one hellp me with sample code please
here is my code to check if textview is empty or not
if( self.info .text.length <= 0 ){
}
1.Make sure your DataSource is something like this a
NSMutableArray *dataSource = [NSMutableArray alloc]initWitObjects:#"One",#"Two",#"Three",#"Four",#"Five",nil];
2.Remove wanted objects from your dataSource like so
[dataSource removeObjectAtIndex:2];
Delete rows in UITableView with animation
Create indexPaths to delete like this
NSArray *deleteIndexPaths = [[NSArray alloc] initWithObjects:
[NSIndexPath indexPathForRow:2 inSection:0],
nil];
Finally delete them from the tableView like this
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
Or you can simply call
[self.tableView reloadData];
Related
In my cellForRowAtIndexPath and I pre selecting a row:
NSArray *tempArray = [[communityPrefs objectForKey:#"Community"] componentsSeparatedByString:#","];
NSMutableArray *tempArrayMutable = [[NSMutableArray alloc] initWithArray:tempArray];
if ([tempArrayMutable containsObject:cell.textLabel.text])
{
[selectedAreaTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
This part works great. However the selected item is at the bottom of the page and the user will not see it, but when they scroll down to that cell it is selected.
Now I am trying to write a piece of code the will deselect all selected cells like so:
for(NSIndexPath *index in selectedAreaTable.indexPathsForSelectedRows)
{
if(index.row != 0)
{
[selectedAreaTable deselectRowAtIndexPath:index animated:NO];
}
}
but after I run this code the cell at the bottom is still selected. So my question is, why is this cell not being deselected? Is it because its not there until you scroll to it? How can I fix this problem?
Is it because its not there until you scroll to it?
Yes. I believe that you should change "selected" state using cell objects only for visible rows. All other rows should retrieve "selected" status in cellForRowAtIndexPath method
user979331,
you dont have to remove the selection in seperate method rather you can handle that too in cellForRowAtIndexPath as well.
You can declare the array NSMutableArray *tempArrayMutable as a property,
when you want to deselect all cell lets assume a method named clear all selection
-(void)clearAllSelection {
[self.tempArrayMutable removeAllObjects];
self.tableView reloadData];
}
Finally in cellForRowAtIndexPath change as
if ([self.tempArrayMutable containsObject:cell.textLabel.text])
{
[selectedAreaTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
else{
[selectedAreaTable deselectRowAtIndexPath:indexPath animated:NO];
}
I have a ViewController that has a TableView generated with Custom Cells. Each Custom Cell has a NSDictionary that generates few arrays.
I want to find the way to replace one array in Custom Cell using [myArray replaceObjectAtIndex:... withObject:...] pointing towards a specific cell in a TableView, provided that I already know the indexPath of that cell that contains that array.
Another words I have to somehow indicate that Custom Cell indexPath, get there and refresh array.
Is there a way to accomplish that mission in Objective-C?
You can get a cell reference using cellForRowAtIndexPath call if you know the indexPath of the cell that you want to change if each of your custom cell is different unique.
But I strongly recommend changing the data model by getting it using cell location as the reference. Because table views reuse cell you could end up with unexpected results. You should instead change your table model and then reload the table or perhaps reload just the specific cells that have changed.
Once you have the indexPath of your cell, you can do something like:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
You got several option for reloading the UITableView taken inside the UIViewController
say your table view is such
UITableView *tableView
case 1: Reload the whole table view appledoc
[tableView reloadData];
case 2: Reload all the rows inside a section appledoc
[tableView reloadRowsAtIndexPaths:yourIndexPath withRowAnimation: UITableViewRowAnimationNone];
case 3: Reload multiple section at once appledoc
tableView reloadSections:yourIndexPathSet withRowAnimation:UITableViewRowAnimationNone];
NB :: must do any of these operation in your mainThread / gui thread.
Solution.
First, we need to make sure that every Custom Cell has a #property NSInteger cellIndex;. When tableView populates Custom Cells, make sure to add cell.cellIndex = indexPath.row;. That way every Custom Cell will have it equal to tableView row.
Second, when making changes in parent viewController, in the end of update we post notification [[NSNotificationCenter defaultCenter] postNotificationName:#"refreshCollectionView" object:self];.
Third, in Custom Cell we listen to that notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refreshCollect) name:#"refreshCollectionView" object:nil];. That triggers method (also included in Custom Cell) with reference to cellIndex:
-(void) refreshCollect {
if (cellIndex == [[[NSUserDefaults standardUserDefaults] valueForKey:#"cellIndex"] intValue]) {
NSURL *newsImgURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.website.com/core/functions/ios/page.news.image?news_id=%#", [[NSUserDefaults standardUserDefaults] valueForKey:#"newsID"]]];
NSData *newsImgData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:newsImgURL] returningResponse:nil error:nil];
newsImgDict = [NSJSONSerialization JSONObjectWithData:newsImgData options: NSJSONReadingMutableContainers error:nil];
newsImgID2 = [NSMutableArray arrayWithArray: [newsImgDict valueForKey:#"image_id"]];
newsImgTime = [NSMutableArray arrayWithArray: [newsImgDict valueForKey:#"timestamp"]];
newsIDImg = [NSMutableArray arrayWithArray: [newsImgDict valueForKey:#"news_id"]];
newsImgDescr = [NSMutableArray arrayWithArray: [newsImgDict valueForKey:#"description"]];
newsImgExt2 = [NSMutableArray arrayWithArray: [newsImgDict valueForKey:#"ext"]];
} }
In my case I have NSDictionary that rebuilds some arrays just for that particular Custom Cell.
This question already has answers here:
How to insert new cell into UITableView in Swift
(5 answers)
Closed 7 years ago.
I am making an app that is using core data, and I have 2 textfields and a button saying "save data".So I want when the button is pressed the data from the textfields is displayed on a new row in a table view controller.In Xcode using Objective C.
Image of views - http://i.stack.imgur.com/7UrMO.png
Thanks
Beginner to programming
Follow these steps:
Step 1: Update your model (used to draw your cell) with textFields text. Something like this:
[self.items addObject:<Object_With_Both_TextFields_Text>]
Step 2: On button tap, insert a new row like this:
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:self.items.count - 1 inSection:0];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
Just add the new data from text fields to your table view data source (mostly this will be a mutable array or dictionary). Then call reloadData on your table view.
Add the entry from text fields into your table view data source.
[yourMutableArray addObject:[textField1 text]];
call [yourTableView reloadData];
When you press 'save data', add content that you want to display into the your_array that you are using to display the tableview.
[your_array addObject:your_textfield_string];
After that reload the table again using [tableview reloadData]:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[tableview reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
////TO SCROLL THE TABLE TO NEWLY ADDED ROW
int lastRowNumber = [tableview numberOfRowsInSection:0] - 1;
NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0];
[tableview scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
});
});
I am trying to remove a cell from my collectionView, however. When I remove the object from my datasource and attempt a batchupdate, it says the cell doesn't exist anymore.:
'NSInternalInconsistencyException', reason: 'attempt to delete item 0 from section 0 which only contains 0 items before the update'
Before this code I remove the content from my core data, and the line [[usermanager getSelectedUser]loadCards]; actually reloads the datasource containing the content for the cells by getting them from the Core Data.
- (void)cardRemoved:(NSNotification *)note {
NSDictionary *args = [note userInfo];
Card *card = [args objectForKey:#"card"];
[[usermanager getSelectedUser]loadCards];
[self.collectionView performBatchUpdates:^{
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:card.position.intValue inSection:0];
[self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
} completion:^(BOOL finished){
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
[self.collectionView reloadData];
}];
}
If I print out the amount of Cells before I call the loadCards line, I get the correct amount of rows(As expected).
EDIT
This is what loadCards calls:
-(NSMutableArray *)getCards{
UserModel *selectedUser = [self getSelectedUserFromDB];
NSMutableArray *cards = [[NSMutableArray alloc] init];
for(CardModel *cardModel in selectedUser.cards){
[cards addObject:[self modelToCard:cardModel]];
}
return cards;
}
I noticed, even if I don't call the loadCards method, It says there are no items in the view.
Can anyone help me out? Thank you
Remove the cells from the UICollectionView, then remove them from the model. The same thing applies to UITableView. You also don't need to reload the collection view after removing items.
If you prefer you can just remove items from the model and then reload the collection view and the items that aren't in the model will disappear from the collection view, but without the same animation that comes from removing items from a collection view.
the doc about reloadData of UITableView says(http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html): "it should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates and endUpdates".
My question is, why? (especially first part, italic).
There's a book which I am reading which implements adding items to the UITableView like this:
// Add new item to the table
- (IBAction)addNewItem:(id)sender
{
// Update the model, add a new item
BNRItem *newItem = [[BNRItemStore sharedStore] createItem];
// Figure out where that item is in the array
int lastRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
// Create the corresponding index path
NSIndexPath *ip = [NSIndexPath indexPathForRow:lastRow inSection:0];
// Insert this new row into the table
[[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:ip]
withRowAnimation:UITableViewRowAnimationTop];
}
whereas same could be achieved also like this:
// Add new item to the table
- (IBAction)addNewItem:(id)sender
{
// Update the model, add a new item
[[BNRItemStore sharedStore] createItem];
[[self tableView] reloadData];
}
By reload data you're forcing all rows to be recreated so when you have information what is new it is just much more performant to tell table view what have to be added/removed, especially when, for example, you added one row at the end and that part is currently not on screen (so view does not have to be re-rendered, only scroll high have to be recalculated).