Search code examples
objective-cios8xcode6uipopovercontrolleruiactivityviewcontroller

iOS 8 UIActivityViewController and/or UIPopoverController are not dissmissed when clicked outside of them


I have read the UIPopoverController docs and more then 10 stackoverflow solutions which none work in iOS 8.0.2 ipad device.

THE GOAL:

I want to present a sharing view which when clicked outside dissmisses.

THE PROBLEM:

The code works fine below iOS 8.0.

THE CODE (tried many versions...):

 NSArray *dataToShare = @[url];  // ...or whatever pieces of data you want to share.
            UIActivityViewController* activityViewController =
            [[UIActivityViewController alloc] initWithActivityItems:dataToShare
                                              applicationActivities:nil];
            activityViewController.modalInPopover = YES;


            self.act = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
            [self.act presentPopoverFromRect:CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, self.view.bounds.size.width/2, self.view.bounds.size.width/2) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
            self.act.delegate = self;

I have added the :

UIPopoverControllerDelegate

WHAT I HAVE TRIED:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

As soon that the

UIPopoverController

is presented the view losses focus and doesn't register touches. Therefore, I can't handle touches outside the self.act rect space in order to force a dissmisal.

also...

NSArray *dataToShare = @[url];  // ...or whatever pieces of data you want to share.
            UIActivityViewController* activityViewController =
            [[UIActivityViewController alloc] initWithActivityItems:dataToShare
                                              applicationActivities:nil];
            activityViewController.modalInPopover = YES;

            UIPopoverPresentationController *presentationController = [activityViewController popoverPresentationController];
            presentationController.sourceView = self.view; // if button or change to self.view.

            [self.parentViewController  presentViewController:activityViewController animated:YES completion:nil];

and I tried to present the UIActivityViewController and UIPopoverController from the parent which didn't work aswell.

Please help, I lost half day on something this stupid which works on iOS 7.1 and not on iOS 8+ which is ridiculous and I still have no clue why.

I will try to add the cancel button which has also disappeared in iOS8+.

UPDATE 1:

Adding a UIButton inside a UIBarButtonItem didn't help...

UIButton *control = (UIButton *) sender;
                [control setFrame:CGRectMake(300, 300, 100, 100)];
                [control setBackgroundColor:[UIColor redColor]];
                UIBarButtonItem *barButtonItemView = [[UIBarButtonItem alloc] init];
                [barButtonItemView setCustomView:control];
                [self.popup presentPopoverFromBarButtonItem:barButtonItemView permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

UPDATE 2 - 19.12.2014. (iOS 7.1. - 8.1.2):

The accepted answer works on iOS 8.1. I had some errors with iOS 7.1. so I modified it to work for iOS 7.1. I have stated on which devices the code works in the comments below the answer.

// publish - sharing
        NSArray *dataToShare = @[url];  // ...or whatever pieces of data you want to share.
        UIActivityViewController* activityViewController =
        [[UIActivityViewController alloc] initWithActivityItems:dataToShare
                                          applicationActivities:nil];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        NSLog(@" SHARING - 1 - ");
        [self presentViewController:activityViewController animated:YES completion:^{}];
    }
    else
    {
        // Change Rect to position Popover
        NSLog(@" SHARING - 2 - ");
        self.popup = [[UIPopoverController alloc] initWithContentViewController:activityViewController];

        [self.popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width * 3 / 5 ,
                                                      self.view.frame.size.width/2,
                                                      self.view.frame.size.width/10,
                                                      self.view.frame.size.width/10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }

Solution

  • How about just add this.

    UIActivityViewController* activityViewController =
                [[UIActivityViewController alloc] initWithActivityItems:dataToShare
                                                  applicationActivities:nil];
                activityViewController.modalInPopover = YES;
    
    activityViewController.popoverPresentationController.sourceView = self.view;