I've made a custom activity indicator (actually just an imageView)
When user clicks something and I expect it will take a bit long to process(alloc a UIViewController and push on to navigation stack),
I alloc the indicator and add it as subview of current view just before the lengthy process starts.
Strange thing is, indicator doesn't show up until the push (left-right) animation starts.
Is it because the lengthy job takes the system, and ui drawing for activity indicator is delayed?
Am I doing something wrong here?
Thank you
Edit
Looks like I can do the "push" in background.. i'm trying it now
IPhone SDK - Leaking Memory with performSelectorInBackground
Is your job synchrone or asynchrone ?
If it's the first case, then it can be the problem.
Check all the method like :
[ self performSelector:<#(SEL)aSelector#> ];
You can thread this to avoid your [potential] problem.
Good luck.
You should process your lengthy tasks in the background. The UI won't update if you block the main thread.
So you have to refactor your app, the alloc and push of the viewController should happen within the blink of an eye, because you can't do this in the background.
But you can do the processing (downloading data I guess) in the background.
There is plenty information available about background processing. The way to go varies heavily on what you want to do exactly.
Related
Currently I encounter an issue somehow, the application lost all those artistic UI animation for example, page flipping, alert view popup, action sheet slide up and etc. That means all those UI will show up immediately without any transition animation. It looked very weird.
Firstly, the app will run smoothly until something trigger the issue above, and after that only re-run the app or kill the app will stop the problem.
There is no error message or any clue that I can figure out what could be the reason. Have any one of you guy has encountered similar issue as above? Please share with me how am I able to solve the issue above. Thanks.
Animations may get disabled for the entire app whenever an attempt is made to animate views on a background thread, e.g. by calling one of UIView's animateWithDuration:animations: family of class methods from a background thread. Be sure to update your app's UI only from the main thread.
You can check if code is running on the main thread by testing [NSThread currentThread].isMainThread and you can ensure it runs on the main thread like so:
dispatch_async(dispatch_get_main_queue(), ^(void) {
// Your code
});
Alternatively, ensure that you're not calling [UIView setAnimationsEnabled:NO] anywhere, as that will also disable animations for the entire app.
I have a MBProgressHUD that shows when data is being pulled on the background asynchronously. Sometimes when the network is slow this will take forever. So as of now I am just hiding it after 30 seconds if it hasn't been dismissed. What is a good way to dismiss this HUD for a slow network connection?
I would say that the best solution is probably to keep the HUD up the whole time the data is loading so that the user knows that something is happening, and perhaps give them an option to cancel it if that is appropriate for your app. Alternatively, if it is possible for you to load and display the data piecemeal (i.e. before you have the entire set of data), then you should just display the HUD until you have enough data that you can start displaying something in the UI that the user can interact with.
Basically, what you want to avoid is a situation where it could appear to the user that nothing is happening and the UI is essentially blank with nothing for them to do.
Implement MBProgressHUD delegate
it will be called every time whether if it is fast or slow network connection,In case of slow network connection there will be a time out and this delegate will be fired,remove the hud from the superview in this delegate
-(void)hudWasHidden
{
[HUD removeFromSuperview];
}
I'm doing an app that uses a TabBarController and each Tab uses its own navigation controller.
The app has dynamic content and I use viewDidDisappear viewDidAppear methods to create or destroy the objects that I need each time I enter or exit into the ViewController.
My problem is when I start to sail very fast and I don't give time to load the Threads that I use for uploading content such as XML peta app or destroy objects when I leave the ViewController.
How I could control the tabs of the navigationbar or tabbarviewcontroller for not respond until the viewcontroller has loaded all contents?
Excuse me if I'm not well expressed. Thanks!
No matter you use synchronous request or asynchronous request, just show an UIAlertView while loading the data. This will both serve as a notification to the user that something is being loaded, and the it will block the interactions with all the other views on the screen.
As others have suggested in comments, I believe that what you want to do is rearrange the order in which things are triggered. Perhaps something like this:
On viewWillAppear:, clear (or disable or whatever is appropriate) your objects that are no longer valid and begin the load-new-content thread. Perhaps display a UIActivityIndicator or similar.
On viewWillDisappear:, tell the load-new-content thread that it can stop, its results are no longer needed. If you put up an activity indicator, take it down.
At the end of the load-new-content thread, take down any activity indicator, update the UI with the new contents and activate.
I don't really see any way around this -- if the UI is not valid until the new content is loaded, then you have to wait for it.
Another solution might be to cache the contents from the previous fetch, and always display those on viewDidLoad. Then, at the end of your new-content-thread, cache the new contents, and update the UI.
I have a UITableView which loads its data from the web. It takes a while to load this data and therefore I would like an acitivity indicator to animate while the data is loading. I am doing the following in my attempt to make this work:
1) In viewDidLoad I add an observer to listen to when the data loading is done and after that I call loadDataFromWeb
2) loadDataFromWeb creates the activity indicator, adds it as a subview to self.view and then it loads the data. At last it posts a notification (the one that viewDidLoad observes) to indicate that the loading process is done.
3) Finally, when the observer catches the post from loadDataFromWeb, it calls removeLoadingScreen to remove the indicator.
Pretty obvious I am not seeing my indicator view. If I comment out the line that removes the indicator, it stays on the screen when everything is loaded. I am aware that I'm probably messing around with which methods are called when in the process, and this is where I need help.
I should mention that the whole purpose is that instead of the user's looking at a screen on which nothing is happening (while the data loads), I want a activity indicator to show up to indicate that there's something going on here.
Thanks
#Muncken have a look at this MBProgresHUD project, this will help you a lot to do a downloading progress in background (secondary thread not main thread) and shows a activity indicator over you view -
https://github.com/matej/MBProgressHUD
I allow the user to manage records on other views. I set a flag if certain changes are made.
Then on the flag (where the data changes will have an impact) I run some methods / queries which create the data which is used in my table view(s). This workload currently happens in viewWillAppear(s).
This could take a few seconds and I'd like to show my progress indicator view which I wrote today, it uses a transparent view with a activity indicator in the center of the view.
[self performSelectorInBackground:#selector(startupStuff) withObject:sender];
However, viewWillAppear won't wait while I run the the work in the background.
Ideally I'm looking for a quick fix to work around this problem.
Any ideas ?
However, viewWillAppear won't wait while I run the the work in the background.
That's the whole point of it, isn't it? At the end of your startupStuff method, you should call another method on the main thread (with performSelectorOnMainThread:...) that is used to (a) inform the controller that your data is ready, (b) reload the table view and (c) dismiss your progress indicator view.