UIActivityViewController activity does not deviate from iPad

I have a subclass of UIActivity 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 will add the full registry on GitHub .


According to the documentation, you should not reject this manually. Instead, the OS does this when calling activityDidFinish: This works great on iPhone.

When I say โ€œworks,โ€ this is the sequence of events that I expect (and see on the iPhone):

  • Display UIActivityViewController
  • User clicks my custom action
  • My view controller will appear.
  • I call activityDidFinish:
  • My user view controller is rejecting
  • Disabled UIActivityViewController

However, when I run the same code on the iPad Simulator, the only difference is that I put the UIActivityViewController in the popup, as the documentation says that you should - activityViewController should never deviate.

As I said, this wo / popUP code works on the iPhone, and I went through the code, so I know that the activityDidFinish: call is being called.

I found that this Radar talks about the same problem in iOS6 beta 3 , but it seems so fundamental functionality that I suspect an error in my code and not in the OS (also note that it works correctly with Twitter and Facebook functions!) .


Am I missing something? Do I need to do something special in the ActivityViewController when it runs in the UIPopoverViewController ? Is it supposed that the "stream" will be different from the iPad?

+7
source share
8 answers

Automatic dismissal occurs only when your "active" controller is displayed directly, and not wrapped up. Therefore, before showing the pop-up window that it is wrapped, add a completion handler

 activity.completionHandler = ^(NSString *activityType, BOOL completed){ [self.popup dismissPopoverAnimated:YES]; }; 

and you will be good.

+7
source

I see that the question is quite old, but we were debugging the same problem with the view controller - we are not quitting here, and I hope that my answer will provide some additional information and a better solution than calling -dismissPopoverAnimated: manually.

The UIActivity documentation is pretty scarce, and although it does indicate a way to structure the implementation, the question shows that this is not as obvious as it could be.

The first thing you should notice is the documentation, in which you should not reject the view controller manually. This is really true.

What the documentation doesn't say, and what appears as an observable thing when you encounter debugging problems with an incompatible view controller is iOS that will call your method -activityViewController , when it needs a topic link, view the controller. As it turned out, probably only on the iPad, iOS doesn't actually store the returned instance manager instance anywhere in its structures, and then when it wants to reject the view controller, it just asks for your -activityViewController for the object, and then fires This. The view controller created when the method was first called (when it was shown) is thus never rejected. Uch. This is the cause of the problem.

How do we fix this?

Removing UIActivity documents further, you can stumble on the -prepareWithActivityItems: method. A specific hint lies in the following text:

If the implementation of your service requires the display of an additional user interface for 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 use it in the instance variable. Then just return the same instance from your -activityViewController method.

Given this, the view controller will be correctly hidden after calling the -activityDidFinish: method -activityDidFinish: without further manual intervention.

Bingo.

NB! Digging this a little further, -prepareWithActivityItems: should not instantiate a new view controller each time it is called. If you have already created one, you should simply reuse it. In our case, it happily crashed if we did not.

Hope this helps someone. :)

+4
source

I had the same problem. He decided for me to save activityViewController as an element and return the saved controller. Actions return a new object and are freed when a new one is called.

  - (UIViewController *)activityViewController { if (!self.detaisController) { // create detailsController } return self.detailsController; } 
+2
source

I go through UIActivity to another view, then call the following ...

 [myActivity activityDidFinish:YES]; 

This works both on my device and in the simulator. Make sure that you do not override the activityDidFinish method in the UIctivity.m file, as I did before. You can see the code I'm using here .

+1
source

The workaround is to ask the calling ViewController to execute a segue on your target ViewController via - (void)performActivity , although Apple does not recommend this.

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; } } 
+1
source

Do you use storyboards? Maybe your iPad storyboard UIActivityIndicatorView doesnโ€™t have a check for "Hides When Stopped"?

Hope this helps!

0
source

So I had the same problem, I had the usual UIActivity with a custom ActivityViewController, and when it was presented modally, it would not reject, no matter what I tried. The work on which I decided to go so that the experience remains unchanged for the user, was to continue to use custom UIActivity, but to give this event a delegate. So in my subclass of UIActiviy, I have the following:

 - (void)performActivity { if ([self.delegate respondsToSelector:@selector(showViewController)]) { [self.delegate showViewController]; } [self activityDidFinish:YES]; } - (UIViewController *)activityViewController { return nil; } 

Then I create a view controller that shows the UIActivityViewController delegate, and it displays the view controller that you would otherwise show in the ActivityViewController in the delegate method.

0
source

how about release at the end? Using the project is not an arc !

[progressView release];

Many users have the same problem as! Another solution:

 UIActivityIndicatorView *progress= [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 50, 30, 30)]; progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; [alert addSubview:progress]; [progress startAnimating]; 

If you are using a storyboard, make sure that when you click on actionind. Click "Hide when stopped"!

Hope that helps ...

-one
source

All Articles