App crash while remove object from TableView - ios

I have multiple data in my UITableView and when I delete one record.

Don't use didEndDisplayingCell to manipulate the cell or the data source array by the passed index path.
It's just a notification that the specified cell was removed from the table
The documentation also states:
Use this method to detect when a cell is removed from a table view, as opposed to monitoring the view itself to see when it appears or disappears.
The solution is to move the entire code in this method to the location where the cell / data source item is removed and use it before removing anything

The app is crashing because even though you have deleted the object( so now array will have one less element) but you have not told the table view to reset itself according to new datasource. Even cellforRowAt will crash if you delete the last element. One solution is to reload the tableview by calling:
<tableViewName>.reloadData()
but it will produce unnecessary flicker if tableViews are quite large and complex. And the Second thing, You should'nt be using didEndDisplayingCell

Related

Preload tableView cells and prevent reloading

I already found entries with that topic on this page and also a website that provides a tutorial for that problem. But nothing worked very well.
The tutorial sad I should double the height of my tableView so cells loaded earlier, but with a higher tableView I never reached the last cells.
My problem is, I use a tableView to display my apps mainpage. This mainPage shows every time a topic and if its necessary for that topic it shows for example a cell with a map, one with pictures and sometimes not. Problem now, if I trying to scroll to my view its always lagging because it loads a map or this pictures. And scrolling back again because the loaded cells already deleted. I used a tableView because of the possibility to switch celltypes(mapCell, pictureCell, textCell) on and off.
I understand this feature, because of memory issues but in my case its not that much and it would be better if all my cells be preloaded and stay in memory until I change the topic.
Is there a swifty way to told my tableView to have this behavior?
Thanks a lot and nice greetings
I would suggest a different approach. Set up your table view controller to install placeholder images in your cells, trigger an async download that you cache to disk, and then update the cell with it's downloaded content if it's still visible when the download is finished.
There are various third party frameworks that do all this housekeeping for you.
Declare a cell array.
Follow these steps whenever change in your topic.
Clear you array
Create and configure all cells add to your array.
Return these cells to datasource methods using row index. Don't use tableview dequeue method here.

TableView rows not updating after core data insert

I'm very new to swift programming. I have been playing around with this for a while, but I am not getting anywhere so asking here.
I have a tableview which I can load the data into the view from CoreData no problem. I have an ADD button at the top that segue's to a new tableview, with a long list of options they can pick from. This tableview also works fine, and includes a search bar.
When the user selects an item row from the second tableview, it inserts that item into CoreData and segue's back to the first tableview. This is where my problem is, the data does NOT update on the visible view.
I call tableview.reloaddata() and I can see my code calling the fetchedResultsController with the new query that would return with the new data. But the code never gets to the cellForRowAtIndexPath func so therefore the visible data view never changes. It remains the same display that was visible when the add button was pressed.
How does the visible data get updated? What am I missing?
When using an NSFetchedResultsController, if you want it to "automatically" update the contents of the tableview then there are a couple of things you need to make sure of...
You have to become the NSFetchedResultsControllerDelegate and implements the methods necessary for the updating of the table view. These are quite lengthy and can be found on the Ray Wenderlich website. The code on here is in Objective-C but it's fairly easy to convert to Swift.
The second thing you need is to make sure that the core data update is done on a background thread. Again the website linked above shows this.
Once you've done that then you don't actually need to run [tableview reloadData] because the fetched results controller methods will manage everything for you.

Writing to coredata when device is put to sleep?

I have abit of a problem, I have a coredata object that is used to populate a UITableView. Each UITableViewCell has a couple of buttons that I am using as check boxes, when the user presses one of these text boxes I would like to update coredata and reload the UITableView so all of the arrays I have are updated to reflect the new data.
Thinking about this I have come to the conclusion that its abit redundant or overkill to be reloading the UITableView every time a button is pressed because some of these UITableViews will contain hundreds of rows with two editable UIButtons each.
So I thought that maybe I should update the current array instead then when the view is either exited or the device is put to sleep I could update the coredata object then? the only thing being I don't really know if this is the right thing to do or possible.
The reason this is such a problem is that when I change a button from say a tick to a cross if I scroll away then come back the buttons tick or cross s reverted to its old value.
I would like to know the best way to handle this case as I have never done anything like this before.
You should use an NSFetchedResultsController and its delegate methods to populate the UITableView. Then when the user taps a button, you simply update the corresponding Core Data entity and not the cell. The NSFetchedResultsController will then call its delegate methods, and you can update just that one cell on which the user made a change.
Also, in cellForRowAtIndexPath, you simple fid the corresponding CoreData entity, and use its attributes/properties to adjust the display of the cell.
Remember, that you must always use some data (NSArray usually) from which to read what to do for the cell at the indexPath when the tableView calls cellForRowAtIndexPath:.
This way, when the fetchedResutsController call its delegate methods, you can simply call reloadCellAtIndexPath on the tableView and then the tableView will call cellForRowAtIndexPath again. As the Core Data entity has been updated, your logic for adjusting the display for that cell will cause the cell to look as it should. It's important that you only ever adjust the way a cell looks in cellForRowAtIndexPath, and base the look on a CoreData entity. Change the look of a cell in multiple places, and you will get problems.

numberOfSectionsInTableView is requested in/after viewDidLoad ONLY if tableview is empty

A simple tableviewController, empty. A modal that can be launched from a button. No data in the data source for the tableview, and no rows displayed.
I open the modal, use it to add an item, and return to the tableview controller. The tableview updates itself automatically, and the new row is displayed.
I add a second item. The table view does NOT update automatically.
I can tell by logging inside numberOfSectionsInTableView that even if I go to add the first item and cancel, the tableview refreshes - it asks for the number of sections, rows, and the cell to display (if there is one). But not if there is one pre-existing row in the table.
I've scoured my code but can't find anything that would cause the tableview to know when the first item is added, but none afterwards.
Any ideas?
EDIT - I have further narrowed my issue so will close this shortly and have posted a more specific question at Why does an empty tableView check the number of sections but a non-empty one does not?
from Apple's documentation:
UITableView overrides the layoutSubviews method of UIView so that it
calls reloadData only when you create a new instance of UITableView or
when you assign a new data source.
maybe you are setting data source of table view after showing that modal? So at the second time data source does not changes and tableView does not update.
another key (I'm not sure about that) may be the showing of the modal first time. The method -addSubview for modal is causing -layoutSubviews.

iOS iterate UITableView

I have a UITableView that collects data from a database. What I would like to know is if there is some way I can iterate in the UITableView collection and check the values of the cell? The reason I ask is because I would like to update each cell based on the current value that it has (change font, size, color, etc.). I've seen in another SO post regarding this topic, but since the cells are already created and their values are changed it is a bit harder for me. I was thinking of iterating through the UITableView before I call reloadData, but any other suggestions are welcome.
You should not iterate over the cells of UITableView, because some of them (in fact, most of them) may not be present until you request them. UITableView aggressively recycles its cells, so if a cell is not visible, it is very likely that you would be creating it from scratch only to put it back into recycle queue moments later.
Changing your model and calling reloadData the way your post suggests would be the right solution. iOS will ensure that it runs the update in a smallest number of CPU cycles possible, so you do not need to worry about the cells that are already created. This is also the easiest approach in terms of your coding effort.
A table view is for displaying data. The properties of your table cells should only be written to, not read from. The appropriate way of handling this situation would be to update your underlying model objects -- the objects that you use to populate the table view -- as the data changes, and then reload the affected rows.
The issue you'll encounter is that UITableView reuses table cells. Once a table cell scrolls off the screen, it's quite likely that the table view will reuse the same cell to display a different row.
This means it's fundamentally not possible to iterate over the table cells. When you need to refresh a row because its data has changed, you should call reloadRowsAtIndexPaths:withRowAnimation: (or reloadData if all rows have changed) and if the row is visible on screen, UITableView will call your data source methods and give you an opportunity to configure the cell for display.

Resources