How can I go about adding a view that appears until the background task finishes (the task in question populates a view and takes ~5 seconds).
Thanks,
Wire a hidden image view in the xib to an IBOutlet, and simply show it before the task starts and hide it when it is over. There is a "hidden" option in the xib inspector's view section. Just before you call the task, use myImageView.hidden = NO;. Depending on what the background task is, you should be able to give the owner of that task a closure block, delegate, or selector that can call myImageView.hidden = YES;
Okay, after much trial and error I found a solution. In my case I wanted to show a view whilst my tabbarviewcontroller initialised, and due to the content within it this took 5 - 10 seconds. So to improve user experience I wanted an image to appear. Peter, the method you posted unfortunately didn't quite solve the problem as despite calling the view to be in view until after the tabview was called to appear, it was removed automatically.
So, what I did was set up an NSTimer for 10 seconds, and after the 10 seconds hide the view. Making sure I had [self.window bringSubviewToFront:imageview]; set to insure the tabbar didn't appear over the loading view.
Related
I get used to put either of viewWillAppear and viewDidLoad, it's OK until know. However I'm thinking there should be some rules that guide when to put into viewWillAppear and when to put into viewDidLoad?
Simple rule I use is this. viewDidLoad is when the view's resources are loaded. The view is not drawn onscreen yet. So calculations and code dealing with the geometry and visuals of the view should not be put here. They should be in the viewWillAppear or viewDidAppear method.
Also viewWillAppear can be called multiple times
When a popover/modal view is displayed and remove
When an alert view/actionsheet/uiactivityController's view is displayed and removed.
For these reason, viewWillAppear should not contain codes that takes longer to finish. (at least the code running on the main thread). Neither should codes that only needs to be run once per view display.
There are more I am sure but these are simple to remember and I hope it helps.
viewDidLoad: Alerts you that a view has finished loading
viewWillAppear: Runs just before the view loads
viewDidLoad is things you have to do once. viewWillAppear gets called every time the view appears. You should do things that you only have to do once in viewDidLoad - like setting your UILabel texts. However, you may want to modify a specific part of the view every time the user gets to view it, e.g. the iPod application scrolls the lyrics back to the top every time you go to the "Now Playing" view.
However, when you are loading things from a server, you also have to think about latency. If you pack all of your network communication into viewDidLoad or viewWillAppear, they will be executed before the user gets to see the view - possibly resulting a short freeze of your app. It may be good idea to first show the user an unpopulated view with an activity indicator of some sort. When you are done with your networking, which may take a second or two (or may even fail - who knows?), you can populate the view with your data. Good examples on how this could be done can be seen in various twitter clients. For example, when you view the author detail page in Twitterrific, the view only says "Loading..." until the network queries have completed.
I have ATMhud. I' m showing hud with progress bar. I want to download actualization then.
But user can back to previous view and stop actualization.
I' m tried push "push black view", but i only cover current view without navigation/tabar.
How i can block clicking everything, before actualization finish?
If I understood your question correctly, you want to prevent user to interact with your view till your loading process is finished. You can set Views userInteractionEnabled property for that.
When you go for loading show at that moment set
self.view.userInteractionEnabled = NO
and after when your process is finished
self.view.userInteractionEnabled = YES
so this way you can prevent user to interact anywhere on your view while process is undergoing.
Hope it helps.
IPhone SDK - Leaking Memory with performSelectorInBackground
seems to suggest you can actually pushViewController in background thread.
But I get a warning from stackoverflow people that I shouldn't do this.
eg. (iphone) start timer from background thread?
is pushViewController considered "UI updating"?
(because I know that UI updating should be done in main thread only)
If it is so,
when a viewController takes a while to load, and want to show an indicator while loading.
What is my option?
Couple of strategies here.
1) BEFORE you do the push, but at the point you know you are going to do it, bring up a suitable activity view on the current view. I do this in some apps where you click on a row in a table but the pushed view has to do some web comms that takes time, so I leave the table cell highlighted in blue and add a white spinner to the left of the disclosure indicator. Works well.
2) Use lazy loading to get the new view controller on screen quickly, but defer the heavy code until after it has loaded so that the new controller can look after it's own activity view. By lazy loading I mean you should do as little as possible in the init method and make careful use of viewdidload / viewwillappear / viewdidappear etc to spread the work out and get an activity view on screen as soon as you can.
Hi there
I ran into some confusion related to this; i would like to perform some actions only once the view is appeared, probably showing an activity indicator while the data is being collected.
I have written my code in viewWillAppear, but it seems to be firing before the view appears on the screen.
I have double checked this with some NSLog statements, and i added a sleep of 2 seconds in viewWillAppear, the NSLog statements get fired, and the view appears only after 2 seconds delay - i was expected, the 2 second delay is executed once the view comes onto the screen?
Am i doing something wrong?
I even tried viewDidAppear, same thing. Any suggestions?
Thanks
edit: I would like to give a clear scenario of what i am doing
1. i have a parent view, which has a scroll view - and a subview
2. In the parent view, i create multiple instances of the subview and add them to the scrollview, creating scrollable views, which work.
3. Each view is passed an argument and depending on the argument the view contents change - works as expected.
4. I would like to show the subview and once its on the screen, do some internet opearations while i show an activity indicator, for this i need to use viewDidApper.
5. I am manually firing the subview's viewDidAppear from the parent view, once i have created its instance
The problem here is, the view is appearing only once all the operations are complete.
How can i sort this?
viewWillAppear is supposed to fire BEFORE the view appears, hence the word Will in the name. You might be interested in viewDidAppear.
I guess i figured it out -
Rather than performing operations on viewDidAppear, i used performSelector, something like this
-(void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self performSelector:#selector(loadXML:) withObject: self afterDelay:0];
}
Thanks guys!
Suppose I have a navigation controller where the next action is to take a picture or select an image from the library.
If I initialize UIImagePickerController during didSelectRowAtIndexPath:, (I believe) the response will be a little slower as the controller needs to initialized. Also, if the user cancels and opens again, it would reinstantiate that controller every time.
However, if I create the controller during viewDidLoad: of the navigation controller, it takes up memory while the user is on that view. Side questions: Does this, however, slow down the loading time of the navigation?
Or should it be done in an NSOperation when the view is loaded?
Overall, what would be the best place to load the ImagePicker?
I'd lazy load the controller when it first gets called (in didSelectRowAtIndexPath) so it wouldn't have to be reloaded every time, and not worry about initialization time.
It seems that in your case you will always need an image picker on didSelectRowAtIndexPath. You can load it on the view and customize (camera, cameraroll, etc.) and present on the row selection. Probably it doesn't matter that much. UIImagePickerController presentation is very slow anyway, especially with the camera.
I don't recommend an NSOperation for this task.