Swift UITableViewController Reduce Loading Time - ios

I'm currently creating an iOS app in Swift 1.2 with a master-detail UITableViewController setup so that MasterTableViewController has cells that push to DetailTableViewController.
DetailTableViewController has fairly complex cells that pull data from a web client to generate a chart, similar to in Apple's Health app. It usually takes about 5-10 seconds for all the data to download.
As a result, there is a 5-10 second delay when a cell in MasterTableViewController is tapped before DetailTableViewController is shown.
I would ideally like to push immediately from the MasterTableViewController to the DetailTableViewController and then display an activity indicator on the DetailTableViewController page that is dismissed when all the data is downloaded.
Could someone point me in a good direction to accomplish this? Thank you! :)
My code is below for pushing from master to detail. Fairly basic. I feel like if I change something in the viewDidLoad or cellForRowAtIndexPath method, I could get this done fairly easily.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
let detailVC = DetailTableViewController()
detailVC.navigationItem.title = "Your Charts"
self.navigationController?.pushViewController(detailVC, animated: true)
}

On your detail view controller you can create a UIActivityIndicatorView variable.
In viewDidAppear you can call the activity indicator, bring it to front and start animating it.
The create a function that populates an array that will store the data your cells will use and re work your cellForRowAtIndexPath to use it. (Instead of fetching the data in each cell).
Then in your function to fetch data, right after (or before) you update your table tell the activity indicator to stop animating.

Related

swift: TableViewCell doesn't change colors

i have a weird bug:
Unfortunatly the app is built rather complicated:
It starts with a "normal viewcontroller" called RootContainerViewController.
In it's viewDidLoad() it instanstiates a UIViewController called InitialViewController using UIStoryboard.instantiateViewController and creates a custom UINavigationController using the constructor with the InitialViewController as root.
It then creates an other UIViewController that holds the RootViewController as member.
Finally it calls
self.addChildViewController(drawerController!)
view.addSubview(drawerController!.view)
while the drawerController does the same with the RootViewController in it's viewDidLoad().
The same procedure with other VCs instead of InitialViewController is executed to swap between some ViewControllers.
One of these other viewcontrollers is again a container that instantiates a ViewController called OnePager and adds it as above. This OnePager conatins a ScrollView with a few containerViews each containing a ViewController. One of these has a UITableView with TableCells that have a custom class. In the tableView(cellforRowAt:) function, the background and font color of 2 of the labels inside the cell are set, which works fine at this time.
when it is iniated it may not have the data already therefore a reloadData is called on the table after the data is loaded.
But when the users swaps back to InitialView(with the same procedure as at the start) and the again to the OnePager, the colors aren't applied anymore. on some cells the isHidden Variable is set to true and that still works, only the colors don't.
Can anyone help me? it's too much code to copy it in here
try it in
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
}
I had kinda same problem in collection view

How to delete a tableView row in VC 1 from a modalVC?

I am using coreData and simply sending data from the tableView cell content that is text and the color of the cell to a modal view controller. In modalVC, I am able to change the text and when I press done, the tableView gets updated.
Now I want to add a feature in which if the text is removed completely and the user press done, the data from coreData should be deleted and so should the tableView row.
Here is what I am doing in order to achieve this:
#IBAction func doneButton(_ sender: Any) {
if edittasktextview.text.isEmpty == true
{
moContext.delete(editnotes[num] as NSManagedObject)
editnotes.remove(at: num)
}
else
{
editnotes[num].sNote = edittasktextview.text
}
}
num is the indexPath which I am sending from the first VC to modal VC (kind of keeping track of which cell is tapped)
Now when I dismiss the modal viewcontroller, a notification is send to the firstVC to trigger a func which essentially reloads the tableView in firstVC. However, while the row is no longer seen in the tableview, I still have have to go back to my rootVC and then back to first VC to update the tableView completely.
Help will be appreciated!
Use an NSFetchedResultsController to let your table view be triggered by CoreData changes.
Here's a tutorial to get you started. There are various other good tutorials and YT videos that are easy to find.

Xcode: TableView cell to create ViewController

I've recently started using Xcode and Beginner to creating apps. I've come across something I'd like to implement but research hasn't been quite clear/complicated to understand.
I have a TableView with Days of Week and also a segmentedControl that duplicates these days 3 times. I'm wondering how I'm able to get user click to take me to an alternative ViewController depending on which day it is and what segment of the segmentedController is selected without having to create 21 viewcontrollers in the storyboard.
I've used a ViewController and made an outlet to a tableView for this setup.
in you tableview delegate method -> didSelectedRowAtIndexPath
you can simply write
let vc = UIViewController()
/*
you can add informations here
*/
present(vc, animated: true)
and inside this method you can use the indexPath to get the cell you've clicked
let cell = tableView.cellForRowAt(indexPath)
now you can get the information in this cell
You can have one viewcontroller which is basically a recipe for the viewcontroller you want to go to.
For example you want to show a viewcontroller with a label that states a combination of the number from the segmented control and the date which the user tapped on.
If you now create a ViewController which has a label in storyboard, the text on the label doesnt matter, you can use code to change the text to anything you would like.
In the tableviewcontroller you can use the didSelect delegate method of your tableview to present the viewcontroller and set the label to the values of the segmented control and the cell which is tapped.
I think you just need some more information about iOS and programming in general, therefore I suggest you watch the following iTunes U course:
https://itunes.apple.com/us/course/developing-ios-10-apps-with-swift/id1198467120
It has everything you need to know
Create a detail view controller with two variables (Ex - dayName and selectedSegmentIndex). And in your current viewController "tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)" push detailsViewController with these details like this
let objViewController: DetailsViewController? = UIStoryboard.mainStoryboard().instantiateViewController(withIdentifier: "DetailsViewController") as? DetailsViewController
objViewController?.dayName = dayName
objViewController?.selectedSegment = segmentControl.selectedSegmentIndex
navigationController?.pushViewController(objViewController ?? UIViewController(), animated: true)

Open URL in different ViewController when tableView cell is pressed

I am using SWRevealViewController for a slide-out menu in my app. The main View Controller contains a WKWebView to open URLs. When the slide-out button is pressed, a table view Controller appears.
I want to have the name of a website displayed in a Table View Cell in the Table View Controller in the slide-out menu and open that website in the WKWebView in the main View Controller when the cell is pressed.
This may seem like an easy question, but I can't seem to find anything about it online.
Thanks in advance for your help.
As far as I remember the implementation of SWRevealViewController, it uses the static table view.
If you are okay with the static table view that will have your links then you may just create a delegate method that will be called based on the cell that was chosen on the Table View Controller. This delegate will notify your ViewController and say which link to open.
Hope it's clear. Let me know if you need more details.
In SideMenuViewController (view controller in which you have table with links)
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let mainViewController = MainViewController()
mainViewController.link = linksArray[indexPath.row]
self.revealViewController().setFrontViewController(mainViewController, animated: true)
}
init new main view controller that have WKWebView
pass link as a property
set that view controller as new front view controller

How to add a view to UINavigationController that is visible above any child view

I'm creating an app which shows data in a UITableView. This data also contains location information, so I want to add a MapView to display this data. When a user taps a UITableViewCel, I need to segue to another UITableView to show the detailed data. I still want to show the MapView with the same data above this detailed data, and I still want the NavigationBar to update, i.e. the back buttons returns the user to the first UITableView.
In image form to make it easier to understand
I was thinking of making a subclass of a UINavigationController and putting the container underneath the MapView, but I don't really know where to go from there.
Have VC0 embedded in a navigation controller or subclass UINavigationController. Create an Info ViewController and push that on the navigation controller.
In your particular case you'll want to use the didSelectRowAt method from UITableViewDelegate.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// use indexPath.section and indexPath.row to use your data
let infoVC = yourInfoViewController()
infoVC.title = "Info Cell Name"
navigationController?.pushViewController(infoVC, animated: true)
}
Edit after first comment:
I'm not sure what the best way of doing this is but one way you can do it is:
Modify your table view based on what is being shown, ie: first set of data or cell detail data
Update the navigation bar's title and left bar buttons per set of data you're displaying
One of those buttons will only appear in the cell detail data set and it sets your switch back to displaying the first set of data

Resources