Inserting a new cell into a collectionview - ios

I try to add a new cell in my UIcollectionView but it doesn't work.
In fact I send a post request to my API, I wait for the response, when I get the response, I put de JSON content into an NSDictionnary.
My CellForItemAtIndexPath Datasource method loads cell content from an array called "formationsData", so when I get the response, I add my NSDictionnary into this array.
In numberOfItemAtIndexPath I return something like : [self.formationData count].
Here is my code when I post my request :
NSDictionary * response = [responseJSON valueForKey:#"formation"];
[(NSMutableArray *)_formationsView.carousel.formationsData addObject:response];
[_formationsView.carousel insertItemsAtIndexPaths:#[[NSIndexPath indexPathForItem: _lastRowIndex-1 inSection:0]]]; //insert at index : last row - 1
//[_formationsView.carousel reloadData]
Before I was using reloadData but my app crash when I do that.
My problem :

Before I was using reloadData but my app crash when I do that.
Then that's the problem you need to solve. Just adding an item to the array you use to populate the collection view isn't enough to make a cell appear. The collection view doesn't have any idea where the data source gets its data; when there's a change to the data, you need to call -reloadData or similar.
If -reloadData causes a crash, then you need to figure out why and fix it.

Related

UITableview not showing content first time

I face one issue of displaying data in the table view. It works fine when I scrolling down and back to the top. I have also table reload in the main queue but it's not working for me. I have referred following link but not getting any solution.
showing-first-time-only-when-scrolling-a-bit Table view cells showing actual data only after scrolling once
I have also reloaded table viewdidapear and also when I got data from the API.
DispatchQueue.main.async {
self.tblDashboard.refreshControl?.endRefreshing()
self.tblDashboard.reloadData()
}
Please find the attached video for the understanding (click here for video) and please see the code files here.
Strange !!
if let aTempArr = result["songs"] as? [[String : Any]] {
//// parsing code here ......
self.tblDashboard.reloadData() ///<---
}
DispatchQueue.main.async {
self.tblDashboard.refreshControl?.endRefreshing()
self.tblDashboard.reloadData()
}
Also, I move the cell method's code into the cellForRowAt indexPath in Tableview controller.

Reloading data from a tableView within a collectionViewCell

I have a tableView inside a collectionViewCell and I get an error when I try to reload the data.
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.6.21/UITableView.m:1610
I tried using Dispatch.main.async and it seems to get rid of the problem. The only thing is that it doesn't reload the data and nothing changes in the tableView
func cleanItems(completion: #escaping (Bool) -> Void) {
Dispatch.main.async {
cell.tableView.beginUpdates()
// Make changes in the Data Source
cell.tableView.deleteRows(at: selectedItems, with: .fade)
cell.tableView.endUpdates()
// Reloading sections accordingly depending on what the user has deleted
// Do I need to reload data here again? It used to work without Dispatch, but it wasn't stable
cell.tableView.reloadData()
// Updating items with if statements to reload data in Firebase
completion(true)
}
}
This doesn't reload the data at all and nothing seems to change. The good thing is that I don't get a random crash, which was the case before implementing Dispatch.main.async
I've retrieved the numberOfRows in each section to see how many rows there are after ending updates.
print(cell.tableView.numberOfRows(inSection: 1))
and I get the same number of rows that are in the current view.
This is crucial, because if the tableView sections are all zero, the collectionViewCell should disappear. And we never get here in the completion block as it says that the numberOfRows has never changed. Leaving us with a non updated tableView.
I solved this by moving Dispatch.main.async outside the function call.
Dispatch.main.async {
cleanItems(completion: { (success) in
etc.
})
}

Error updating UITableView after smaller sized JSON response?

Currently, I have my app hitting my endpoints, and getting back 10 or less items. In the event the items returned is less than 10, and the UITableView is already showing 10 items, reloadData() will cause an error because the size is not the same as it was last time. Right now, when I get my response all I do is:
tableView.beginUpdates()
self.items = items //where self.items is the array that backs the UITableView, and items are the items I got back in form of JSON from the server.
tableView.reloadData()
tableView.endUpdates()
Why will it cause error? If you are using tableView.reloadData(), you don't need to call endUpdates() and beginUpdates(). Just simply assign the items and reload tableView data.
self.items = items
tableView.reloadData()
If you are on the background thread call the above code on the main queue.
dispatch_async(dispatch_get_main_queue()) { () -> Void in
// Code runs on main queue!
}
It is not your calling reloadData that caused error. It is because your numberOfRowsInSection or numberOfSectionsInTableView didn't return right value after you update your model.
In the table view method,
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {}
you should write as , return [self.items count];
This way, your table will know, how many items your table need to show, and reload data would not complain.

reload cell data in table view with Swift

how is it possible to reload data for a cell in my table view? I want to do a request to my Server and the server responses JSON. At the moment I implemented the request and the response handling and I can show the data in my cells. But I want that the server only responses maybe ten datasets. When I scroll to the end of the table view with my ten cells in the app I want to do the next request to my server and the server delivers the next ten datasets and so on. I work with Swift as the programming language.
THX!
You can use self.tableView.reloadData() in order to reload your entire table or self.tableView.reloadRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimation.None) in order to reload a specific cell.
You can read more about the UITableView class here
To reload visible cells of tableview in Swift 3.0
pTableView.beginUpdates()
pTableView.reloadRows(at: pMessagesTableView.indexPathsForVisibleRows!, with: .none)
pTableView.endUpdates()
Try this...
Swift 2.0
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
Swift 3.0
DispatchQueue.main.async {
self.tableview.reloadData()
}
you can get Array of visible Cell by using TableView Function tableView.visibleRows() or You Can Get IndexPath of Visible Rows By tableView.indexPathsForVisibleRows() ! and then you can reload table by tableView.reloadData() Function!
look at following links
link1
you can read about UITableView Class Here

Delete dynamic cell in GetCell method

I am trying trying to remove a cell from the UITableView if the image for the cell is a bad image. Basically my code does a threadPool call for each cell's image to make the flow of binding the data as a user scroll smooth as so inside the GetCell method:
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
//other stuff
ThreadPool.QueueUserWorkItem(new WaitCallback(RetrieveImage),(object)cell);
}
within that asynchronous method I call the cell.imageUrl property and bind it to an NSData object as so:
NSData data = NSData.FromUrl(nsUrl); //nsUrl is cell.imageUrl
From there I know that if data==null then there was a problem retrieving the image so I want to remove it. What I currently do is set the hidden property to true, but this leaves a blank space. I want to remove the cell entirety so the user won't even know it existed.
I can't set the cell height to 0 because I don't know if the imageUrl is bad until that indexrowpath initiates getcell call. I don't want to just check all images from the data thats binded to the UITableView because that would be a big performance hit since it can be easily a hundred items. I am currently grabbing the items from a webservice that gives me the first 200 items.
How can I remove the cell altogther if the data==null example
NSUrl nsUrl = new NSUrl(cell.imageUrl);
NSData data = NSData.FromUrl(nsUrl);
if (data != null) {
InvokeOnMainThread (() => {
cell.imgImage = new UIImage (data);
//cell.imgImage.SizeToFit();
});
} else {
//I tried the below line but it does't work, I have a cell.index property that I set in the getCell method
_data.RemoveAt(cell.Index);//_data is the list of items that are binded to the uitableview
InvokeOnMainThread (() => {
//cell.Hidden = true;
});
}
You remove cells by removing them from your source and then you let UITableView know that the source has changed by calling ReloadData(). This will trigger the refresh process. UITableView will ask your source how many rows there are and because you removed one row from your data, the cell representing that row will be gone.
However ReloadData() will reload your entire table. There is a methods which allows you to remove cells specifically, named DeleteRows(). You can find an example here at Xamarin.
When deleting rows it is important that you update your model first, then update the UI.
Alternatively, I recommend you to check out MonoTouch.Dialog which allows interaction with UITableView in a more direct way. It also includes support for lazy loading images.

Resources