Dismiss popover when iPad app goes in background - ios

Hi I am working on a iPad app and got a requirement to dismiss all popovers (if any) when app goes in background.
I did some study online and didn't find a simple way to do it. I'd like to share some my idea here and see if there are a better way to do it.
1, Dismiss popovers in didEnterBakcground in delegate. Seems not practical since we have to add all popovers reference in.
2, Go through all views recursively in current window to find popover view by (class = _UIPopoverView). It is seems a bit hacky and dangerous.
3, Set up UIApplicationDidEnterBackgroundNotificationgroundNotification in each object who own popovers and dismiss them. This seems reasonable, but really troublesome if there are hundreds of popovers in your app.
4, How about add a category method say -(void)dismissWhenAppWillEnterBackground; and register notification.
Or there is easier way to do it?

Here is a drop-in category on UIPopoverController that does what you're asking.
Basically the category swizzles initWithContentViewController: so that it can track live UIPopoverController instances in a NSHashTable (which doesn't itself hold the contained UIPopoverControllers alive since it keeps weak references to them.) It also monitors for UIApplicationDidEnterBackgroundNotification, and when this arrives it iterates the collection of live UIPopoverControllers and dismisses any that are showing.
It might be nice to extend this to implement the "never allow two popovers to show at once" rule that Apple has.
I'm not a huge fan of method swizzling in production apps but this seems pretty safe.
No special instructions for use. Just include the category in your project and use your UIPopoverControllers normally.
#import <objc/runtime.h>
#interface UIPopoverController (autodismiss)
#end
#implementation UIPopoverController (autodismiss)
static NSHashTable* ts_popoverHashTable;
+ (void) load
{
SEL originalSelector = #selector(initWithContentViewController:);
SEL replacementSelector = #selector(ts_initWithContentViewController:);
Method originalMethod = class_getInstanceMethod( [UIPopoverController class], originalSelector);
Method replacementMethod = class_getInstanceMethod( [UIPopoverController class], replacementSelector);
method_exchangeImplementations(originalMethod, replacementMethod);
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector( applicationDidEnterBackgroundNotification: )
name: UIApplicationDidEnterBackgroundNotification
object: nil];
}
- (id) ts_initWithContentViewController: (UIViewController*) contentViewController
{
UIPopoverController* pc = [self ts_initWithContentViewController: contentViewController];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
ts_popoverHashTable = [NSHashTable weakObjectsHashTable];
});
[ts_popoverHashTable addObject: pc];
return pc;
}
+ (void) applicationDidEnterBackgroundNotification: (NSNotification*) n
{
for ( UIPopoverController* pc in ts_popoverHashTable )
{
if ( pc.isPopoverVisible )
{
[pc dismissPopoverAnimated: NO];
}
}
}
#end

I may have a better answer, which is add a category method -(void)dismissWhenAppWillEnterBackground to UIPopoverController and register UIApplicationWillEnterBackgroundNotificationgroundNotification.

Write a protocol with a couple of optional methods:
- (void)appWillEnterBackground;
- (void)appWillBecomeActive;
Make your view controllers to implement it and then in your app delegate, access your root view controller, check if it responds to those methods and invoke them when the app is going to background and becoming active.
You should be able to obtain the root view controller easily. If you have a hierarchy of view controllers you may need to forward the call.
Add your popover dismissal code in appWillEnterBackground, for instance.

Create a uiviewcontroller base class for all the view controllers in the application.
Add an array which contains the references to the popover views in the particular viewcontroller
Maintain a reference to the current viewcontroller iin app delegate .
When app enters in background, get the current viewcontroller and travers the popover array and dismiss all the popovers.

Related

iOS - Monitoring app flow from AppDelegate

I am trying to create Singleton that it would be initialised from AppDelegate. The purpose is to monitor all the UIViewControllers (the active one) and print on console the kind of class (as proof of concept). So my basic idea is to initialise the singleton in AppDelegate and pass as parameter a reference of AppDelegate. Then somehow I must monitor which one is the active view.
For example: View A B C
A is the first view in Navigation Controller. My Singleton knows that the current view is A. Then we push view B and Singleton is notified that view B is now the current view. Same with C. Now we pop C and Singleton knows that the current view is B.
Is any kind KVO or NSNotification for notifying my singleton that a new UIView is appeard/removed? Any alternatives for this problem?
After registering for all notification I found out about UINavigationControllerDidShowViewControllerNotification.
With this observer:
[notifyCenter addObserver:self selector:#selector(viewAppeared:) name:#"UINavigationControllerDidShowViewControllerNotification" object:nil]; I am able to monitor the activity of the UINavigationController.
You can get current View controller by just making a view controller object in appdelegate like
#property (strong, nonatomic) UIViewController *currentViewController;
and then on the view will Appear of your current view controller give the current reference to the app delegate object like
AppDelegate *myAppd = (AppDelegate*)[[UIApplication sharedApplication]delegate];
myAppd.currentViewController = self;
This way you get your current active view.
One approach is to pick a particular method you want to know about and intercept it.
Here, I create a category on UIViewController and provide a method I want called whenever the controller's viewWillAppear: would normally be called:
#include <objc/runtime.h>
#implementation UIViewController (Swap)
+ (void)load
{
NSLog(#"Exchange implementations");
method_exchangeImplementations(
class_getInstanceMethod(self, #selector(viewWillAppear:)),
class_getInstanceMethod(self, #selector(customViewWillAppear:)));
}
- (void)customViewWillAppear:(BOOL)animated
{
// Call the original method, using its new name
[self customViewWillAppear:animated];
NSLog(#"Firing %# for %#", VIEW_CONTROLLER_APPEARED, self);
[[NSNotificationCenter defaultCenter] postNotificationName:VIEW_CONTROLLER_APPEARED
object:self];
}
#end
After that, it's just a case of listening for the notification in whatever object needs to know (e.g. your Singleton).

Am I properly using delegation? If not, how should I be doing this?

So I have taken the plunge into Objective-C programming for iOS development. I have a little app that I am working on, nothing special, but something to help teach me the ropes. The problem I am having is as follows:
Currently, I have two classes. The first being
ViewController
and the second being one that I created myself called
UserDecision
The View controller shows what is on screen, and UserDecisions currently takes the information from buttons pressed on screen, and performs the proper logic on it while working with my model class. My issue is, that I have an update UI method in UserDecision which needs to update the button properties (text, visibility, etc.) in ViewController if certain events take place. Because of this, I can't user an instance of ViewController because I won't be able to access the buttons on screen. So for this I created a delegate system:
#protocol updateUIDelegate <NSObject>
-(void)hideAll;
-(void)makeBackVisible;
-(void)updateOutput:(NSString *)output;
-(void)updateChoices:(NSString *)choices;
-(void)updateTrueButton:(NSString *)trueString;
-(void)updateFalseButton:(NSString *)falseString;
-(void)removeChoiceFromArray;
#end
The above protocol is defined in UserDecision.h, and then I assigned my ViewController as my delegate:
#interface ViewController : UIViewController <updateUIDelegate>;
And then I flush out said methods in my ViewController.m:
#pragma - updateUIDelegates -
//Called when the last screen is displayed
-(void)hideAll{
[_trueButton setHidden:true];
[_falseButton setHidden:true];
[_choicesText setHidden:true];
[_backButton setHidden:true];
[_resetButton setHidden:false];
}
//Makes back button visible
-(void)makeBackVisible{
[_backButton setHidden:false];
}
//Updates the text on the false button
-(void)updateFalseButton:(NSString *)falseString{
[_falseButton setTitle:falseString forState:UIControlStateNormal];
}
//Updates the text on the true button
-(void)updateTrueButton:(NSString *)trueString{
[_trueButton setTitle:trueString forState:UIControlStateNormal];
}
//Updates the output text box
-(void)updateOutput:(NSString *)output{
[_outputText setText:output];
}
//Updates the choices textbox
-(void)updateChoices:(NSString *)choices{
if(!choicesArray){
choicesArray = [[NSMutableArray alloc] initWithCapacity:4];
}
//If this is the first button press, add string to array and display
if([_choicesText.text isEqualToString:#""]){
[choicesArray addObject:choices];
_choicesText.text = [NSString stringWithFormat:#"%#", choices];
}
//Otherwise, add the new string to the array, and print the array
//using a comma as a way to concatinate the string and get rid of
//the ugly look of printing out an array.
else{
[choicesArray addObject:choices];
[_choicesText setText:[NSString stringWithFormat:#"%#",[choicesArray componentsJoinedByString:#", "]]];
}
}
//Removes the last choice from the array
-(void)removeChoiceFromArray{
[choicesArray removeLastObject];
[_choicesText setText:[NSString stringWithFormat:#"%#", [choicesArray componentsJoinedByString:#","]]];
}
This allows me to call theses methods by sending them as a message to self.delegate in my UserDecision class when needed.
This is my current setup. My issue has become that I want to create a modal seque view that pops up at the end (after a user presses a button to bring up the view), and which can be dismissed afterward. The problem I have is that this view, from the reading and research I have done online, can only be dismissed through delegation, unless I want things to get nasty. Now, I tried to implement this information in my class, but then I read that a class can only be a delegate to one other class. And since my ViewController(which is my main window) is already a delegate of my UserDecision class, I can't make it a delegate of the new View I have created, and thus can't dismiss the view. So, I am here to ask for your help. How can I go about solving this issue?
Also, for more of my code, should you want to have a look, here is a link to my gitHub: https://github.com/Aghassi/Xcode/tree/master/Bubble%20Tea%20Choice/Bubble%20Tea%20Choice
I read that a class can only be a delegate to one other class. And
since my ViewController(which is my main window) is already a delegate
of my UserDecision class, I can't make it a delegate of the new View I
have created
I don't believe that's true. You can make ViewController implement many different protocols, therefore being delegates to different classes/objects.
For example: (UITableViewDelegate and UITextViewDelegate can both be implemented on the same ViewController for 2 separate objects (UITextView and UITableView).
As for using delegation to close modal windows, another option is to use blocks as well.
It is possible for a viewController to dismiss itself. Just hook up a dismiss button to a function that calls something like:
[self.presentingViewController dismissViewControllerAnimated:YES];
or
[self.navigationController popViewControllerAnimated:YES];
Dismissal can be done with a delegate pattern but it is not required for everything.
You viewController class can be a delegate of multiple objects so it should be able to dismiss the modal view. The only issue is if its a delegate of multiple objects of the same class you may need to check which object is calling it.
Look at the tableView delegate methods as an example, the tableView calls them passing itself as the first parameter.
To dismiss a custom modal view you would define a different protocol anyway so there would be no problem with calling the same method.
See example below:
#protocol OSImageViewControllerProtocol <NSObject>
- (void)dismissImageViewer;
#end
#implementation OSImageViewController
- (void)loadView
{ //LOG(#"loadView called");
scrollView = [[ImageScrollView alloc] init];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[scrollView addGestureRecognizer:doubleTapRecognizer];
self.view = scrollView;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer {
//LOG(#"scrollViewDoubleTapped called");
[self.delegate dismissImageViewer];
}
#end
#implementation ViewController
-(void)browseImage:(UIImage*)image
{
OSImageViewController *_imageViewerController = [[OSImageViewController alloc] init];
UIImage *img = [[UIImage alloc] initWithData:UIImagePNGRepresentation(image)];
_imageViewerController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imageViewerController.modalPresentationStyle = UIModalPresentationFullScreen;
_imageViewerController.delegate = self;
[self presentViewController:_imageViewerController animated:YES completion:^(void){
[_imageViewerController setImage:img];
}];
}
- (void)dismissImageViewer {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
I believe you want to display a modal view from your ViewController.
Let the the modal view be managed by say ViewController2. In ViewController2.h declare a protocol of ViewController2
#protocol viewController2Delegate
-(void)dismissViewController2;
#end
Now make ViewController implement this protocol
#interface ViewController : UIViewController <updateUIDelegate,viewController2Delegate>
Add the method to the ViewController.m
-(void)dismissViewController2
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Now whenever you push a modal view(managed by ViewController2) from ViewController you set the delegate to self. Your ViewController.m code might look like this
ViewController2 *objViewController2 = [[ViewController2 alloc]init];
objViewController2.delegate = self;
[self presentViewController:objViewController2 animated:YES completion:nil];
Hope this solves your problem
COMMUNICATION PATTERNS
Delegation is one of the communication patterns that more or less loosely coupled objects use to communicate each other. iOS Framework provides the following patterns: KVO, Notification, Delegation, Block, Target-Action.
In general, there are cases where the choice comes down to a matter of taste. However, there are many cases that are pretty clear cut.
It's also important to note that the use of each of this patterns results in a certain level of coupling among objects involved into the communication process.
Let's focus now on Delegation, Block, Target-Action.
DELEGATION
Level of coupling (proportional to the level of mutual ignorance) : loose
It allows us to customize an object’s behaviour (decoration) and to be notified about certain events (callback). In this case, the coupling is pretty loose, because the sender only knows that its delegate conforms to a certain protocol.
Since a delegate protocol can define arbitrary methods, you can model the communication exactly to your needs. You can hand over payloads in the form of method arguments, and the delegate can even respond in terms of the delegate method’s return value. Delegation is a very flexible and straightforward way to establish some sort of blind communication between two object that should be loosely coupled for design reason. Let's think to the communication mechanism between a tableview and its dataSource delegate.
Conversely, if two objects are that tightly coupled to each other that one cannot function without the other, there’s no need to define a delegate protocol (use composition instead). In these cases, the objects can know of the other’s type and talk to each other directly. Two modern examples of this are UICollectionViewLayout and NSURLSessionConfiguration.
TARGET-ACTION
Level of coupling : very loose
Target-Action is the typical pattern used to send messages in response to user-interface events. Both UIControl on iOS and NSControl/NSCell on the Mac have support for this pattern. Target-Action establishes a very loose coupling between the sender and the recipient of the message. The recipient of the message doesn’t know about the sender, and even the sender doesn’t have to know up front what the recipient will be. In case the target is nil, the action will goes up the responder chain until it finds an object that responds to it. On iOS, each control can even be associated with multiple target-action pairs.
A limitation of target-action-based communication is that the messages sent cannot carry any custom payloads. On the Mac action methods always receive the sender as first argument. On iOS they optionally receive the sender and the event that triggered the action as arguments. But beyond that, there is no way to have a control send other objects with the action message.
BLOCK
Blocks are usually used to pass to an object a behaviour to be executed before its lifecycle end. Besides, they can also substitute delegates with a caveat relevant to the potential creation of retain cycle.
self.tableView.didSelectRowAtIndexPath = ^(NSIndexPath *indexPath) {
...
[self.tableView reloadData];
...
}
In this case the sender retain the table view whose selection block retain the sender so we'd better use delegation pattern.
An example in which block communication shines:
self.operationQueue = [[NSOperationQueue alloc] init]
Operation *operation = [[Operation alloc] init];
operation.completionBlock = ^{
[self finishedOperation]
}
[operationQueue addOperation:operation];
There's a retain cycle in the above code as well, but once the queue removes the operation, the retain cycle is broken.
Blocks are a very good fit if a message we call has to send back a one-off response that is specific to this method call, because then we can break potential retain cycles. Additionally, if it helps readability to have the code processing the message together with the message call, it’s hard to argue against the use of blocks. Along these lines, a very common use case of blocks are completion handlers, error handlers, and the like.
A CHART HELPING US TO MAKE THE RIGHT CHOICE
source: objc.io
In your specific case, I'd use the target-action communication pattern to dismiss the presented modal view controller.
For example,
ModalViewController *modalViewController = [[ModalViewController alloc] init];
[self presentViewController:modalViewController animated:YES completion:^{
[modalViewController.closeButton addTarget:self action:#selector(dismissModalViewControllerAnimated:)
forControlEvents:UIControlEventTouchUpInside];
}];

Is there a way to distinguish between which UIPopOver is dismissed?

I have several popovers in my application and I am having difficulty in determining which popover was dismissed. Is there a "tag" feature equivalent for UIPopOvers?
I can NSLog the popoverController in the popoverContorllerDidDismissPopover method and see the memory reference of each one but that doesn't help.
#pragma mark - Popover controller delegates
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
NSLog(#"Popover dismised %#", popoverController);
}
An extract from here:
If I understand the question, then basically, no - and it's maddening.
On the one hand you're told that only one popover should be showing at
any one moment. On the other hand you don't automatically get a
reference to that popover. Thus it is up to you to store a reference,
manually, to the current popover controller at the time it shows its
popover, so that you can talk to it later in order to dismiss it.
Popover controller management can thus get really elaborate and
clumsy; you're doing all kinds of work that the system should just be
doing for you.
iOS is funny this way. I'm reminded of how there's no call in iOS 4
that tells you current first responder. Obviously the system knows
what the first responder is, so why won't it tell you? It's kind of
dumb. This is similar; the system clearly knows useful stuff it won't
share with you. m.
There are many ways how to distinguish between popovers. I will list few of them:
You are asking about tag. Note that every popover has a content view controller and this controller has a view that can be tagged. However, using magic integer tags to distinguish between views is arguable in general.
Store the type of the popover into a variable/property in your controller, e.g. as an enum. This is the simplest way.
Add the neccessary information to the popover, but be clever about it, e.g.
#interface MyPopoverController : UIPopoverController
#property (nonatomic, copy, readwrite) void (^dissmissHandler)(void);
#end
#implementation MyPopoverController
- (id)initWithContentViewController:(UIViewController*)contentView {
self = [super initWithContentViewController:contentView];
if (!self) {
return nil;
}
self.delegate = self;
return self;
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController*)popover {
assert(popover == self);
if (self.dissmissHandler) {
self.dissmissHandler();
}
}
#end
MyPopoverController* popover = [MyPopoverController alloc] initWithContentViewController:...];
popover.dissmissHandler = ^{
...
};
As #Anoop stated, you can usually only have one popover showing at a time.
One possible solution is to check the contentViewController property on the pop over. If you are storing a reference of each view controller you could do something like:
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
if ( popoverController.contentViewController == self.someUIViewController ) {
// do stuff
}
else if ( popoverController.contentViewController == someoTherViewController ) {
//
}
NSLog(#"Popover dismised %#", popoverController);
}
If storing a reference to each content view controller is not possible (or maybe just not a good idea), you could always check its type:
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
if ( [popoverController.contentViewController isKindOfClass:[MyAwesomeViewController class]] ) {
// do stuff
}
else if ( [popoverController.contentViewController isKindOfClass:[MyOtherViewController class]] ) {
//
}
NSLog(#"Popover dismised %#", popoverController);
}
Another possible solution, which is probably better from a design stand point of view, would be to pass in a delegate to the view controller contained in the pop over. More here. This way, the view controller displayed can send data back to your main view controller.

UIActivity activityViewController not dismissing on iPad

I have a UIActivity subclass that creates its own activityViewController:
- (UIViewController *)activityViewController {
WSLInProgressViewController* progressView = [[[WSLInProgressViewController alloc] init] autorelease];
progressView.message = [NSString stringWithFormat:NSLocalizedString(#"Posting to %#...",#"Posting to..."),
self.activityType];
return progressView;
}
I've add a full repro on GitHub.
According to the documentation, you aren't supposed to dismiss this manually. Instead, the OS does that when you call activityDidFinish:. This works fine when ran on an iPhone.
When I say "works," this is the sequence of events that I'm expecting (and see on the iPhone):
Display the UIActivityViewController
User presses my custom activity
My view controller appears
I call activityDidFinish:
My custom view controller is dismissed
The UIActivityViewController is also dismissed
However, when I run this same code on the iPad Simulator -- the only difference being that I put the UIActivityViewController in a popup, as the documentation says you should -- the activityViewController never dismisses.
As I say, this is code wo/the popUP works on the iPhone and I have stepped through the code so I know that activityDidFinish: is getting called.
I found this Radar talking about the same problem in iOS6 beta 3, but it seems such fundamental functionality that I suspect a bug in my code rather than OS (also note that it works correctly with the Twitter and Facebook functionality!).
Am I missing something? Do I need to do something special in the activityViewController when it's run in a UIPopoverViewController? Is the "flow" supposed to be different on the iPad?
The automatic dismissal only appears to happen when your 'activity' controller is directly presented, not wrapped in anything. So just before showing the popup it's wrapped in, add a completion handler
activity.completionHandler = ^(NSString *activityType, BOOL completed){
[self.popup dismissPopoverAnimated:YES];
};
and you'll be good.
I see the question is quite old, but we've been debugging the same view-controller-not-dismissing issue here and I hope my answer will provide some additional details and a better solution than calling up -dismissPopoverAnimated: manually.
The documentation on the UIActivity is quite sparse and while it hints on the way an implementation should be structured, the question shows it's not so obvious as it could be.
The first thing you should notice is the documentation states you should not be dismissing the view controller manually in anyway. This actually holds true.
What the documentation doesn't say, and what comes as an observable thing when you come across debugging the non-dissmissing-view-controller issue, is iOS will call your -activityViewController method when it needs a reference to the subject view controller. As it turns out, probably only on iPad, iOS doesn't actually store the returned view controller instance anywhere in it's structures and then, when it wants to dismiss the view controller, it merely asks your -activityViewController for the object and then dismisses it. The view controller instantiated in the first call to the method (when it was shown) is thus never dismissed. Ouch. This is the cause of the issue.
How do we properly fix this?
Skimming the UIActivity docs further one may stumble accross the -prepareWithActivityItems: method. The particular hint lies along the following text:
If the implementation of your service requires displaying additional UI to the user, you can use this method to prepare your view controller object and make it available from the activityViewController method.
So, the idea is to instantiate your view controller in the -prepareWithActivityItems: method and tackle it into an instance variable. Then merely return the same instance from your -activityViewController method.
Given this, the view controller will be properly hidden after you call the -activityDidFinish: method w/o any further manual intervention.
Bingo.
NB! Digging this a bit further, the -prepareWithActivityItems: should not instantiate a new view controller each time it's called. If you have previously created one, you should merely re-use it. In our case it happily crashed if we didn't.
I hope this helps someone. :)
I had the same problem. It solved for me saving activityViewController as member and return stored controller. Activity return new object and dismiss invoked on new one.
- (UIViewController *)activityViewController {
if (!self.detaisController) {
// create detailsController
}
return self.detailsController;
}
I pass through the UIActivity to another view then call the following...
[myActivity activityDidFinish:YES];
This works on my device as well as in the simulator. Make sure you're not overriding the activityDidFinish method in your UIActivity .m file as I was doing previously. You can see the code i'm using here.
a workaround is to ask the calling ViewController to perform segue to your destination ViewController via - (void)performActivity although Apple does not recommend to do so.
For example:
- (void)performActivity
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[self.delegate performSomething]; // (delegate is the calling VC)
[self activityDidFinish: YES];
}
}
- (UIViewController *)activityViewController
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
UIViewController* vc=XXX;
return vc;
}
else
{
return nil;
}
}
Do you use storyboards? Maybe in your iPad storyboard, the UIActivityIndicatorView doesn't have a check on "Hides When Stopped"?
Hope it helps!
So I had the same problem, I had a custom UIActivity with a custom activityViewController and when it was presented modally it would not dismiss not matter what I tried. The work around I choose to go with so that the experience remained the same to the user was to still use a custom UIActivity but give that activity a delegate. So in my UIActiviy subclass I have the following:
- (void)performActivity
{
if ([self.delegate respondsToSelector:#selector(showViewController)]) {
[self.delegate showViewController];
}
[self activityDidFinish:YES];
}
- (UIViewController *)activityViewController
{
return nil;
}
Then I make the view controller that shows the UIActivityViewController the delegate and it shows the view controller that you would otherwise show in activityViewController in the delegate method.
what about releasing at the end? Using non-arc project!
[progressView release];
Many Users have the same problem as u do! Another solution is:
UIActivityIndicatorView *progress= [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 50, 30, 30)];
progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
[alert addSubview:progress];
[progress startAnimating];
If you are using storyboard be sure that when u click on the activityind. "Hides When Stopped" is clicked!
Hope that helped...

Saving state for presentModalViewController in iOS application

I am creating a application where I require a filter button. When I click on filter button, ModalViewController will pop from the bottom of the screen.
[self presentModalViewController:filterActivity animated:YES];
When I am done with that filter screen I am dismissing it with
[self dismissModalViewControllerAnimated:YES];
Now problem is when I dismissModalViewController then all the date entered in UITextField is gone. Is there any way to save the data or save the state of presentModalViewController ?
A standard way to accomplish this is to create a protocol that has say a method "- (void)userUpdates:(NSDIctionary *)dict", and have the master view controller implement it. Give the modal view controller a "#property (non atomic, weak) id delegate" property, and set it before running the modal object. Then, if the user does update some info, provide it back to the master controller using the protocol.
I solve the problem. By using Singleton pattern I have solve the problem. Now I can see data in text filed or label even if i dismiss the modalviewcontroller and come back again. Code for Singleton
+ (MNActivityFilter *) sharedManager {
static dispatch_once_t once;
static MNActivityFilter *sharedManager;
dispatch_once(&once, ^ { sharedManager = [[MNActivityFilter alloc] init]; });
return sharedManager;
}

Resources