When running my app on my device, I have a button that brings up a new view controller. In the function viewDidAppear of the new view controller, I begin processing a bunch of data previously entered. This data takes about 15 seconds to be processed. At the top of this new view controller is a navigation bar with a Bar Button Item where the user can touch it to return to the home page. However, during the first 15 seconds while the app is processing the data, the navigation bar and the Bar Button Item is completely unresponsive. Is there any way to be able to interact with the user while processing data at the same time?
https://developer.apple.com/LIBRARY/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html
Use dispatch_async to launch the 'processing' and dispatch_main if/when it needs to update the UI.
Not Swift, but Ray Wenderlich has a couple of tutorials:
http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
http://www.raywenderlich.com/60749/grand-central-dispatch-in-depth-part-1
Related
In my app the first time the user accesses a page it downloads the data for that section. The app sends the user to the download page the first time and after everything is downloaded it continues on the content.
I have a very roundabout way of doing it now using Userdefaults. Is there a nice way to dismiss the current view controller and segue to a new one at the same time.
The views are embedded in a navigation controller so ideally, I want to remove the download view controller from the stack as soon as it's finished downloading so if the user hits back, it goes back to the main menu rather than back to the download page.
I am trying to create an app that swipes over through multiple view controllers on a UIScrollView - similar to how one would see different windows in the safari app, but instead of tapping a button to move between them, I am swiping the scroll view.
Now, I will be getting notifications when any of the data in a particular view is to be updated with some json. Should I be updating the view that aren't showing (but are on the scroll view), or should I wait until the user scrolls to that view?
I am very concerned about performance here. Hopefully I am being clear in the question.
Thanks!
You should update the views next to the view that you are viewing I would say. And when you switch (scroll) to another view, then update the views next to that view. (Assuming you have received new JSON data)
I have the need for an activity indicator view in my app when different views are loading and when data is being retrieved. The problem is the mainVC (where I would place the indicator) is not always aware of when processing is happening so it can start the indicator but it cannot stop it.
e.g. the mainVC loads and then programatically adds a new VC - this VC in turn asks a model to retrieve - it displays data etc. So this newly added VC actually knows when processing is finished and it does not have access to the indicator view (although the indicator is visible at the top).
I was thinking of using notifications - is this the best way of handling this situation?
I'd recommend looking at the brilliant MBProgressHUD library:
https://github.com/matej/MBProgressHUD
It's a very simple set of classes you can use to display loading and progress views that can be accessed by all view controllers in your app. Basically, you can set it up in your app delegate and add it to your app window.
Every view controller can then access the progress view from the delegate and show/hide it when required. It comes with an example project and code - it's very easy to use and customise.
Notifications are one half of the solution. You have to combine them with a persistent object so that you can also get the current state at all times. E.g., when a view controller is about to appear, it needs to read the initial "downloading" state from somewhere, because the VC might have been created after the "start" or "end" notification was sent.
Then, while the VC is alive, it can simply respond to notifications to update the indicator.
This design is particulary important for views, which run the risk of getting unloaded/reloaded all the time.
Here's the deal:
I have a navigation-based project with a menu screen as the root view. When I tap a button on the menu screen, the navigation controller pops a KalViewController onto the stack (kal calendar).
The calendar appears, and for about a 6 second period the calendar is downloading JSON data from the internet to populate the calendar with events. However, if the user taps Back (to go back to the main menu) during this time, the app crashes or the calendar continues to load the data even when I am on the main screen. (evidenced by the network activity indicator continuing to spin)
1-- I was wondering if there is any way, when I tap the Back button, to cancel that download process so that my objects will release properly? (maybe using threads??)
OR
2-- Somehow prevent the user from tapping the back button while the data is still downloading. (Similar to how a UIAlertView prevents a user from clicking anything on the screen except for 'OK' to dismiss the alert message)
PLEASE help! Thank you very much in advance!
In my iPhone application, a user selects an item from a UITableView to choose a resource to view. The UIViewController subclass required to handle the resource is not known until the resource is retrieved, which may take a few seconds.
In response to the selection action, I push a "loading" view controller on the nav stack. That controller presents a view with a UIActivityIndicatorView along with (possibly) other status information, and initiates the download of the selected resource. From this view, the user might cancel the download, in which case I would return to the list of resources. If the resource arrives, though, an appropriate new view controller is created corresponding to its type.
Here's where it gets sticky. If I push the new type-specific view on the nav stack, the "loading" view is still in the stack; obviously once the loading is complete, there's no need to "go back" to that view. I've tried simply adding the type-specific view as a subview of the "loading" view, but that doesn't get my type-specific controller onto the nav stack, so it doesn't have a [self navigationController] for further navigation.
How can I "replace" the current view on the nav stack with a new one? Or, more generally, how can I show activity / progress when I don't yet know what controller will be used to display the resource being retrieved?
I've found pretty cool "HUD" progress indicator classes, but I don't want the progress indication to appear on top of the list of items being selected from. Instead, I want the user to perceive that they have "gone" to a new space that is waiting to be filled in.
I'm pretty new at this stuff, so I hope I've at least worded the question coherently. Thanks for any help anyone can provide.
Update: Actually, it would probably be better to display your "loading" view as a modal view. Check out this question for a few examples.
You should pop the "loading" view controller and push the "specific" view controller once the latter has been downloaded and allocated. Play around with NOT animating one or both of those actions to see what gives the best experience.