I used xcode's premade Master detail application and built off of that. For the tableview, I am making a json request and storing that into coredata; and trying to populate the table based on that coredata.
The way it works, is that the user logs in and then a request is made for a user's specific team. The resulting title and url are saved into coredata and used to populate the tableview/detail view.
Although the coredata is being updated (printing out the logs), the tableview itself is never being updated. I have tried putting self.tableView.reloadData() in viewDidLoad, viewDidAppear, and viewWillAppear; I have also tried creating a timer that calls the reloadData every .4 seconds (current code) and I never see the table cell's textLabel updated. However, if I tap on a cell, the link that is loaded in the detail view IS updated. So to re-iterate, the coredata is being updated, but the table never updates its label text.
If I stop running the app through xcode and then run it again, then the tableview is populated with the labels; but changing the team/user leads to the same results (the coredata/links are updated and the text labels are not)
My code is definitely not the cleanest/best, just trying to get it to work at the moment.
Here's my MasterViewController.swift: https://gist.github.com/aryanaziz/a9791a82061f156afdb9
EDIT: Found the issue.
I was using the self.tableView.beginUpdates() function but was never using the self.tableView.endUpdates() which was causing problems. Removing the beginUpdates() had the tableview behaving like normal.
Found the issue. I was using the self.tableView.beginUpdates() function but was never using the self.tableView.endUpdates() which was causing problems. Removing the beginUpdates() had the tableview behaving like normal.
Related
I've read 3 pages of google results and none worked for me, here's detailed description of the problem:
Every time I launch my app If I tap on the tab bar item that shows the vc that contains my table view it is empty. I have to go to another tab and return to it, just then my table view fetches. Spent 8h trying to fix it already.
Same exact VC shown with a button tap is displayed correctly and loads every time.
What i've already tried:
triple checked if I have:
tableView.delegate = self
tableView.dataSource = self
Tried moving the fetching to viewDidAppear or viewWillAppear, none worked.
Diagnosed it, number of sections is returned but number of rows = 0, cellForRowAt never executes on first tab bar click, even tho my posts are fetched correctly.
Tried fixing any constraints that exist, didn't work.
It simply seems like tableView.reloadData() doesn't work. I surrender, please help me!
You still haven’t provided a very clear picture. At a glance, though, I’d say you need to add a call to your table view’s reloadData() method inside the braces on your call to posts(for:completion:). (I’m guessing about the exact name of that function since you don’t include it.)
If your posts(for:completion:) invokes its completion handler on a background thread then you’ll need to wrap your call to reloadData() in a call to DispatchQueue.main.async() (Since TableView.reloadData() is a UIKit call and you can’t do UIKit calls on a background thread.)
The code might look like this:
StartTestingViewController.posts(for: UUID as! String) { (posts) in
DispatchQueue.main.async {
self.posts = posts
self.tableView.reloadData()
}
}
(I didn’t copy your whole viewDidLoad method, just the bit that calls your function that fetches posts.)
The UITableView.reloadData() method tells your table view “The number of sections/rows of data or their contents may have changed. Please re-ask your data source for contents and re-build your cells.” The table view will ask for the number of sections again, ask for the number of rows in each section, and ask for enough cells to fill the table view’s frame with cells.
If you don’t call reloadData() your table view has no idea that there is new data so it doesn’t reload itself.
I suspect that the reason that you can go another tab and come back and see your data is that the data has been loaded while you were on another tab, and so is available immediately. I’d have to see the exact details of your tab displaying code to be sure.
I am using UITableView to show a list of records. My table allows refresh from top and bottom. On refreshing from top, the old records remain visible until new data is fetched. After the data is fetched, all the records from the array are removed and new records are filled. Then as a final step I refresh the tableview to reflect the newly fetched data.
All works like a charm.
BUT...
Its causing a crash when we do monkey testing. During the top refresh, when the data is being fetched, if I keep scrolling, pulling the tableview, after several attempts there comes an unlucky moment when array is being removed to add the new records but at that time UITableView is also laying out the cells due to constant pulling. This causes the crash.
An easy fix would be to empty the tableview when doing a top refresh but that don't look good as far as the ui aesthetic is concerned. Also if the call fails I won't have anything to show to the user.
I tried by encapsulating the refreshing code in tableview's beginUpdate and endUpdate block but that won't run as there is no change in the tableview itself (i.e. no adding/deleting).
Any help would be appreciated.
Since you say you scroll away and crashes is probably because you try to insert data to indexes that are no longer visible. You should somehow check at what index you are before trying to update the table.
Some code would help me better understand.
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
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.
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.