UIActivityIndicatorView with UITableView in Navigation Controller - iphone

I am working on a an application which is very simple
a navigation controller with a table view
when the user clicks a row, he is directed to the details view.
However, the details view pulls data from Core Data. i am pulling a relatively large amount of data that takes about three seconds to load.
I wanted to add that UIActivityIndicatorView to show progress.
I tried to start the animation once the user clicks the row, so i set it to animate in didSelectRowAtIndexPath
For some reason, the Activity Indicator doesn't start before the pushing of the details view.
Any idea why? or the best way to implement such an idea?
~Adham

Because you start the animation and then start a large operation in the same thread. Consider running that 3 second operation in a new thread. Look at NSOperationQueue and then create a NSOperation to run that procedure. It will work this way.

The UI doesn't update until the end of your run loop. You are, in sequence, displaying the activity monitor, then pushing the new table view, and then the UI updates. You need to change this order.
You can either move something to a different thread, or you could perhaps delay the loading of the new table view by calling performSelector:afterDelay: with a delay of 0. That will delay the loading of the new table view until after the activity indicator appears in the UI. Now, it's still all on the same thread, so you will be blocked from doing anything, but if the animation is threaded in the activity monitor, it would make for a quick and easy solution.

Call method in thread:
[NSThread detachNewThreadSelector: #selector(loadMethod) toTarget:self withObject:nil];
See following for more details:
http://iphone.zcentric.com/?s=UIActivityIndicatorView

Related

UIActivityIndicatorView Between Table Views

I have an iPhone app that starts in a table view and goes to a different table view when the user selects a cell. The two table views are in separate classes (or whatever the proper Objective-C term is, ie. 2 different .h and .m files), and the second table view makes a request from a server based on the selection in the first table. There is a noticeable delay and I've been trying to put a UIActivityIndicatorView up when that happens, but that only displays for a split second when view segues to the second table view. I know this is an issue with threading, but I can't get this to work following any of the other posts on this topic. I call my startAnimating in didSelectRowAtIndexPath and the stopAnimating in the viewDidDisappear. I have also tried using the following code to get this to work by calling it in the didSelectRowAtIndexPath: [activityIndicator performSelectorInBackground: #selector(startAnimating) withObject: nil]; How do I make the activity indicator (or any loading animation for that matter) to work when the server request is going on?
I see that this is a frequent problem on Stack Overflow, but I did just find a working solution. I found this forum iphonedevsdk.com/forum/tutorial-discussion/… My issue was a synchronous connection taking up my main thread, so starting the spinner and then calling the connection in a separate method does the trick.

UIActivityIndicator while loading data into UITableView

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

(iphone) show custom activity indicator?

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.

Have can I show a progresss indication when I'm doing my work before the tableview is loaded?

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.

Refreshing a UITableView

I have a UITableView subclass and a UITableViewCell subclass that I'm using for cells. I'm bulding all my cells in advance and store them in an array from where I use them in cellForRowAtIndexPath. Aside from this I have a thread that loads some images in each cell, in the background. The problem is that the cells don't get refreshed as fast as the images are loaded. For example, if I don't scroll my table view, the first cells only get refreshed when all cells have been modified and the thread has exited.
Any ideas on how I can effectively refresh my tableview/cell?
Have you tried calling [cell setNeedsDisplay] but on the main thread?
setNeedsDisplay when called on a background thread does pretty much nothing,
try this:
[cell performSelectorOnMainThread:#selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
Are you using a callback to notify the controller of your tableview that the images have been loaded? If not, that would be an ideal method.
When the image loads, fire off a callback to the table view controller that sets the image on the cell, and then calls reloadData on the tableView.
This way whenever a new image loads, the table will update to display it.
Not sure exactly what you are trying to achieve with the images - but can I guess they are coming from a server and that is why you want to download them in another thread?
I would not try to load up the cells before you display the table - you should use lazy loading as much as possible to make sure you are making the most of the memory on a device.
My suggestion would be to look at using a subclass of NSOperation to manage the loading of images. Firstly NSOperation will handle all the complexity of threading for you and allow you to queue up the operations. You will then be able to prioritise the operations that you want completed for the cells at the top.
As each operation completes you can make a call back to the cell or tableViewController (perhaps create a delegate protocol to make this really easy).
If you have an operation per image/cell combination then you should be able to refresh each cell as the operation completes. Doing this along with prioritising the operations will give you an optimal solution.
If the NSOperations sound complex or you are put off by this - please do try it - it is a lot simpler than I might have made it sound.
Have you tried calling [cell setNeedsDisplay]?