How to show progress of download in a custom UITableViewCell with ASIHTTPRequest? - objective-c

I'm trying to implement a list language packages that can be downloaded by selecting a custom UITableViewCell that contains a UIProgressBar. For each language package I want to show the download progress. I get this done by setting this delegate setDownloadProgressDelegate:.
Everything works great except when the UIProgressBar is moved out of the visible area. This makes sense because the delegates progress bar is removed. What can I do to stop the app from crashing and how can I display the progress bar if it returns to the visible area?
Hier is a picture to see what it looks like right now.
Thx

I suppose you could use a class of your own (or even the view controller) as progress delegate. In your view controller you could hold an array of references to all progress bars currently in use. You would create one progress bar per download and hold it in the array (thus the object would not be destroyed). Whenever a cell is being created you now have to check your array for the corresponding progress bar object instead of creating a new one. Whenever a download is done and the progress bar is no longer needed, you remove it from the array.
Beware of possible multithreading issues and if necessary (e.g. if your notifications could arrive in another thread than the main thread) use performSelectorOnMainThread: to update the progress bar array and the progress bars within.

Related

Questions about creating 'Camera Roll'-esque functionality

I am fairly new to Objective-C so forgive my ignorance ahead of time =] Here is what I have so far:
The application is a tab bar style application
The view, as relevant to this post, contains several buttons that when clicked pull down different types of images
On click of the button an Array is populated with the data returned from the web service
A new view is displayed with a UIImageView inside of it
Now here is what I am hoping to get clarification on (or simply ideas)
As I said the application itself is a tab bar style app but I am having some trouble with the third view I've added. Currently when I click on a button the view loads correctly but it is loading inside of the Tab Bar view area. This isn't optimal and I would like for this new view to be displayed overtop of the Tab Bar thus taking up the entire area on the phone. I am opening this view from inside the View Controller that contains the button (which is a tab view) like this:
UIViewController * browsePictures = [[UIViewController alloc]initWithNibName:#"PictureGalleryViewController" bundle:[NSBundle mainBundle]];
[self.view addSubview:browsePictures.view];
On this third view I have a UIImageView (I am not sure this is the correct view for the app) that needs to be populated via the data that is returned from the web service. Returning binary data, as I found out, is very inefficient via JSON so I am returning URL's which means I will need to make a call out to the web for every image returned. I am ok with this I am just curious if there is a better way to do it.
The functionality I am trying to achieve with this third view is similar to the Camera Roll functionality of the iPhone. In this case when the user gestures to the left or the right it would move the current index of the array up or down one and load the next photo in the array. I am not sure how to implement this functionality.
I think that is all for now. Thanks!

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.

Loading UIViews in the background on application launch

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.

Overlapping UIViewController subview content despite separate navigation controllers

I have a custom UIViewController called ProductDetailViewController, it has lots of subviews and each of the subviews' content is populated by data requested from a remote server.
There are two ways you could end up looking at a product detail view: in one tab of a tab bar controller you can browse to a product and one gets pushed onto the stack of the navigation controller specific to that tab, or in the other tab you can scan a barcode and a ProductDetailViewController gets pushed onto a separate navigation controller within that tab.
The strange thing happening is that if you have a product detail up in one tab, and then bring one up in the other, when you switch back to the first tab you see overlapping duplicate subview content, as in there are two labels/product images/tableviews stacked on one another within the one view.
FYI:
Nothing ever goes wrong with the second instance you push onto a nav controller stack, it's always the first one that this happens to, as if subviews were added into the existing controller as well as the new instance. I don't think there are two entire product detail views being stacked - the view has a solid background color, so it would hide the one beneath. I'm quite certain I'm pushing to separate nav controllers. At first I thought maybe the incoming data was being sent to both controllers, but that wouldn't account for multiple instances of UI elements overlapping.
Has anybody ever run into anything like this? It's a first for me for sure, and it's driving me nuts.
Screenshot of overlapping product name label subviews:
Somewhere in your code you have a lot of [myview addSubview:anothersubview]
Probably you duplicating subviews when you updating ProductDetailViewController.
Try to insert next code before u start to populate all subviews
[[myview subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
The issue is that many of the subviews aren't actually created until data is received, and the application makes use of NSNotificationCenter to determine when data has been returned and what class and function should receive it. I should have mentioned the use of NSNotificationCenter initially, but it hadn't crossed my mind that it could be this type of problem.
I send a string to my API response notification class as an identifier, and by changing that from being the same between all ProductDetailViewControllers, to a unique value by concatenating the requested URL to my string, my problem has been solved.

NSCollectionView not updating subviews on data change

I have set up an NSCollectionView through Interface Builder. My prototype view contains a progress indicator and a text field. I have set up the bindings so that my "task" object maintains the value of the progress indicator and the text field value.
It all works okay when I add new objects to the collection (via [NSCollectionView newItemForRepresentedObject:] which I add to my array controller). The initial value of the progress indicator and the text field get set appropriately. However, when the values change, it is not reflected in the prototype view. The values always keep their initial value.
I have tried adding a pointer to the prototype view in the "task" object and trying to force an update via [NSView setNeedsDisplay:TRUE] but to no avail. I have subclassed the prototype view and gave it an outlet to the progress indicator so that I could inspect it to see its value at runtime and strangely enough, even though the view is created successfully, the progress indicator is not! Quite contradictory to the fact that it does in fact display and maintain an initial value!
Is there any way I can, using the current setup, propagate the changes to the view?
Thanks in advance.
Your bindings setup should be sufficient.
What is your progress indicator bound to? Make sure it is sending out KVO notifications when the progress value is updated.