Loading UIViews in the background on application launch - objective-c

I have a simple iPad application with 5 views. On the first view, the user is asked to make some selections and set some options. From this information, the other 4 views are programatically changed after an NSNotification message is sent to them. (i.e controls are added, updated).
My problem is that when the application is first loaded, the user sees View1, but View2, View3, View4 and View5 have never been opened yet, so any changes I make programatically to those views are not done and when the user navigates to them (via the tab bar) for the first time, no changes are shown.
[EDIT: I should point out that the code for making the changes to each view is contained within the ViewController itself, and is executed when the view observes the incoming NSNotification. When the view is not loaded, it understandably never received the incoming NSNotification.]
Only after the user looks at any of those screens at least once and then goes back to View1 and makes changes, are the other Views updated properly.
I thought I could get around this issue by actively loading Views 2,3,4 and 5 into memory on application start, so that they are ready to begin receiving notifications right away.
Is there an easy way to do this in iOS 5?

Why do the view changes straight away?
I would store an indicator of the changes needed when the users answers the questions on the first view and then apply the changes on -viewDidLoad of each view that needs to be changed.

Instead of trying to load the views into memory, I'd suggest you initialize these views with the options that the user set on the first view. What I usually do in such situations, when I have a global parameters that are used in many places, I create a utility class to keep the data, make it a singleton, then access the shared instance in the viewDidLoad in the views that use the data during initialization.

Related

Two views displaying live data at the same time

I have two view controllers which should work like described below:
First view controller displays a view which has a table in it. The table contains data which is constantly changing. I have a delegate method for reloading the data when a change occurs. So that is taken care of. When the user selects a row in the table I would like to display a second view which would also contain live data in text format (one UITextView which would constantly change).
I would like to allow the user to access view 1 while view 2 would still be monitoring and displaying live data and vice versa. While user is on view 2, view 1 should still be monitoring and displaying any changes in the table content.
I guess its like having two view controllers present at the same time and switching between them.
What is the easiest or the most standard way to accomplish this? I dont mind if its all done programatically.
It's a little hard to tell what you're asking here. First, views shouldn't be processing data at all -- they should only be displaying it. It sounds like what you're describing is having a background process that updates to your second view. That process could certainly be running while your table is on screen, and when you switch to the second view, you can update it using this running process. Exactly how you would do this depends on the details of what you're trying to do. So, I think we could help you better if you provide more context on what kind of process you want going on that updates your second view, and how choosing a row in your table affects that process.
After Edit:
You can certainly do what you want to do. I think the main thing is that you need to have a property (typed strong) in your first view controller that points to your second view controller, so that when you go back to the second controller a second time, it goes back to the same instance. Based on the selection from the table, you can start whatever process you need to populate your text view, and that process can keep running even after you go back to the table view, since that controller won't get deallocated when it's view goes off screen (due to the strong reference you have). You would just have to have some sort of if clause in your second view controller to know whether the user has selected the same row again, and if so, just show the updated text view, rather than starting a new process.
That's about as specific as I can be without more detail from you.
what you have is a problem where you need a custom parentviewcontroller
look into splitviews as one example :: SplitView like Facebook app on iPhone
cool intros of how to do custom container view controllers :: Container View Controller Examples

View not updating before automatic Segue away from itself

Essentially I have a view controller where the user picks from three choices. Once the user chooses something, the view segues away to another view controller that displays some information regarding their choice for about 5 seconds and then segues back to original view controller automatically where the User must make more choices... (its basically a loop until something is accomplished).
The problem I am having is when the User touches their option, it seems to just segue back to itself without ever displaying the intermediary screen. I added a sleep(5); to the viewDidLoad but all that causes it to do is pause on the original choice screen for 5 seconds before segueing to itself. I also put in an NSLog in just to make sure it was actually using the new controller, which it is indeed.
I didn't include code since its so trivial. viewDidLoad on the new controller, has sleep(5) and the call to segue back to the original view controller.
I solved the problem by moving the code to viewDidAppear. Should have done that from the beginning honestly, just didn't think it through enough I guess.

add a subview to a not-showed uiview

I'm dealing with a weird problem: I've got a UIViewController to handle a list of items to download via inapp purchase.
When a user choses the product to buy, all the purchase flow begins. At this particular moment, I push a UILabel and a progress bar to display the current state of the download.
If, before that, a user choses to go in another part of the application (i.e. by tapping an item form the tab bar menu ), the application continues the purchasing process from there (that is reduced down to saying yes to a couple of dialog boxes and inputing the itunes store account credentials).
The process (that is attached to a background thread) runs smoothly till the end of it, but if the user comes back to the store view the UILabel and the progress bar are not show, I mean, they are initialized and running but they're not visible.
Is there a right way to behave in that circumstance?
Do I have to force the refresh of the view, or do I have to remove'em from the superView and push'em back again?
thank in advance,
hope I'd be clear enough, otherwise don't be afraid to ask, I'll be glad to
explain myself in a more deep and clear way.
-k-
Without a code it is difficult to give you the exact solution.
A possibility is that when you moved out from the original UIViewController the system did unload the view on that controller. It is possible that with this unload the progress bar and label were not destroyed (because over-retained by your view controller or not nil-ed in the viewDidUnload method) but when you entered in the view controller again the view was reloaded from scratch (typically from the nib) with new progress and labels.
So it is correct that you retained the progress bar and label (even if there are better ways to achieve the same result) but you must add them to the view controller view in the viewDidLoad method. A typical way to do this is to store a "active" progress bar in a dictionary and when the view is reloaded from the nib it must be added to it. As soon as the download finish you can remove the progress from both the dictionary and the view. There are other ways to accomplish the same result, so my suggestion is just to give you an idea.
So in order to see if my answer is correct, you must check the viewDidUnload method, add a breakpoint on it and see, once it has been triggered and when you come back to your original view, if the progress bar has disappeared or not.
Hello Holographix u havnt posted any code so it would be difficult to tell
well it seems like the object of Uilabel and progress bar are getting released the time u comes back to the view.

Are modal view controllers the preferred way to replace the entire interface on an iPad?

Specifically, I have something like a game, with a menu screen made out of standard components. I want a button to switch to another view controller that the user will interact with for a while, then return to the menu screen. It seems like having the menu controller present the 'game' mode as a modal view controller is the most straightforward solution, but is this the best way to essentially replace the entire view? Is the whole menu (which may later become a deep nav or split controller) kept in memory as long as the modal controller is in front, and is this something I should bother to worry about?
There are really two parts to this question:
Which method of transitioning from one view to the next in an iPad application provides the best experience to the user?
Which method of transitioning from one view to the next is easiest to implement and best handles memory management?
I'm not going to try to address the first part of this question other than to point you to Apple's 'iPad Human Interface Guidelines' which says (among other things):
Reduce Full-Screen Transitions
Closely associate visual transitions with the content that’s changing. Instead of swapping in a whole new screen when some embedded information changes, try to update only the areas of the user interface that need it. As a general rule, prefer transitioning individual views and objects, not the screen. In most cases, flipping the entire screen is not recommended.
When you perform fewer full-screen transitions, your application has greater visual stability, which helps people keep track of where they are in their task. You can use UI elements such as split view and popover to lessen the need for full-screen transitions.
http://developer.apple.com/library/ios/prerelease/#documentation/General/Conceptual/iPadHIG/DesignGuidelines/DesignGuidelines.html
However, in your case I'd have thought a full-screen transition is entirely appropriate (but then I'm not a user experience expert).
In answer to the second part, yes displaying a new view controller modally seems like a good approach to take.
By default both the objects used by the menu view and those used by the modal view will be kept in memory - but the great thing about using UIViewController sub-classes is that they've got some default memory management built-in. If your application receives a memory warning whilst the modal view is being presented in full-screen mode, the menu view controller's views will be removed and it's 'viewDidUnload' method will be called. So in your implementation of this method you should release any objects you don't need and then recreate them as needed in the menu view controller's viewDidLoad method (which will be called again before the menu view is shown).
This is explained in more detail in the UIViewController class reference:
When a low-memory warning occurs, the UIViewController class purges its views if it knows it can reload or recreate them again later. If this happens, it also calls the viewDidUnload method to give your code a chance to relinquish ownership of any objects that are associated with your view hierarchy, including objects loaded with the nib file, objects created in your viewDidLoad method, and objects created lazily at runtime and added to the view hierarchy. Typically, if your view controller contains outlets (properties or raw variables that contain the IBOutlet keyword), you should use the viewDidUnload method to relinquish ownership of those outlets or any other view-related data that you no longer need.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

Where should I put some code for loading application data?

I have a tab-bar and navigation controller application (like Youtube app or Contacts app).
Where is the correct place to have the code for loading some data from the web? These data are necessary for all the tabs of the Tab Controller and the app can't display anything before all data are downloaded and parsed from the app (except a loading indicator view of course).
Up to now I put it in the AppDelegate but it somehow doesn't feel right..
What's the correct way to do it?
Thanks!
For a simple application, doing this in the application delegate is okay. I would probably do it in my main view controller, however. I would also probably put some defaults on those tabs so that the user sees something there, even if there is no internet connection (although this may vary between apps, and may not be appropriate in your case).
The most important thing to remember is that wherever you start loading this data (whether it's in the app delegate or your controller's viewDidLoad method), you should kick-off whatever downloads you need and establish whatever notification system is appropriate and return as quickly as possible. I.e., don't block in either of these delegate methods.
In general, though, since it sounds like this data is related to the display you are creating, it's probably appropriate to contain it's loading inside the view controller itself.