UIActivityViewController is not working in iOS 11

Try this:

    dispatch_async(dispatch_get_main_queue(), ^{
         UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItemArray applicationActivities:nil];

         activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAirDrop]; 
         dispatch_async(dispatch_get_main_queue(), ^{
               [self presentViewController:activityVC animated:YES completion:nil];
         });
    });

I had same problem, but in Swift3 and it works fine.


For swift 4.0

let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [shareItem], applicationActivities:nil)
activityViewController.excludedActivityTypes = [.print, .copyToPasteboard, .assignToContact, .saveToCameraRoll, .airDrop]

DispatchQueue.main.async {
   self.present(activityViewController, animated: true, completion: nil);
}

All code that modifies the user interface needs to be run in the main queue, that's by design. So all you need to do is this:

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItemArray applicationActivities:nil];

activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAirDrop]; 

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentViewController:activityVC animated:YES completion:nil];
});

A little more explanation: dispatch_async() will enqueue the block you pass to it to run in a near future when it will be safe to update the UI. If you don't do that on the main queue, weird things can happen (sometimes the UI simply doesn't change, or old changes can be applied after newer ones, or stuff like that).

Methods that are messaged from user actions in the UI (for example, in IBAction when you tap a button) already run on the main queue, so dispatch_async() is not necessary there (of course, assuming you're not calling those IBActions manually from another queue).

Note that alloc/init and setExcludedActivityTypes: don't update the UI, so there's no need to call those on the main queue.