Subview shown when loading, hidden when done
-
21-09-2019 - |
Question
My Setup:
In my iPhone app, I have a loading View (which is an UIImageView itself) and two subviews on the loading View, an UIIndicatorView and an UILabel. To view it, I call the [self.view addSubview:loadingView]
method, and to hide it i use [loadingView removeFromSuperView]
.
In my app to refresh my data i have the method -(void)refreshData
. in this method, I show the Subview, download some data resulting from an HTTP POST, and start and NSXMLParser with this data.
when the NSXMLParser reaches the last element of it's -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
method, it then hide the subview (using the above method).
To call the refreshData
method i have a refresh button in my Navigation Bar:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshData)];
My Issue:
When I click the refresh button the subview does not show. It calls the methods because in the Log I clearly see:
Showing Loading View
Bunch of lines shown during the loading process (totalling 15 seconds)
Hiding Loading View
I also know that my methods work because when I comment out the one that hides the view the Loading View continues to be seen until I close the app
Any ideas?
Solution
If you are doing the hiding and showing all within the same event callback, you haven't gave it a chance to actually update the gui. If your work is going to take alot of time(like the 15 seconds), you could use NSOperation to do the operation and have when the finish callback occurs then hide your view.
this might be easier for you to use: http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/NSInvocationOperation_Class/Reference/Reference.html#//apple_ref/occ/cl/NSInvocationOperation
When you want to update the gui, make sure you do from the main thread not from the event in the NSOperation method:
You can use this method to run the selector in the main thread. http://developer.apple.com/iphone/library/documentation/cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:
For a better answer: In the code doing the loading the one that was doing the work to get the data do:
// Code to show loading gui
[[[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(refreshData) object:nil] autorelease];
Then for refreshData:
- (void) refreshData {
// do the work
[self performSelectorOnMainThread:@selector(doneRefresing)
withObject:nil waitUntilDone:NO] ;
}
OTHER TIPS
From the docs:
If the receiver’s superview is not nil, this method releases the receiver. If you plan to reuse the view, be sure to retain it before calling this method and be sure to release it as appropriate when you are done with it or after adding it to another view hierarchy.
Therefore by using 'removeFromSuperview' you are actually releasing the object as well as removing it from its superview.