2

I am working on Share extension & I have one query related to this.

Is it possible to open full view controller in Share extension, also can we add UITableView or other IBoutlet using Storyboard in Share extension.

Thanks in advance

Zoeb S
  • 695
  • 1
  • 7
  • 21

1 Answers1

6

Step1: Add new UIViewController named MainPageViewController.

Step2: Add new View Controller in MainInterface Storyboard, change it's class to MainPageViewController in Custom Class section of Storyboard, set Storyboard ID to MainPageViewController in Identity section.

Step3: Open Share extension's info.plist

By default it looks something like this-

<key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <string>TRUEPREDICATE</string>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.share-services</string>
    </dict>

Now instead of the default NSExtensionMainStoryboard key use NSExtensionPrincipalClass key, so the final result will be

<key>NSExtension</key>
        <dict>
            <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <string>TRUEPREDICATE</string>
        </dict>
            <key>NSExtensionPrincipalClass</key>
            <string>HomeViewController</string>
            <key>NSExtensionPointIdentifier</key>
            <string>com.apple.share-services</string>
        </dict>

Where HomeViewController is our new entry point controller.

Step4: Now, the most important we need to fix weird issue related with module naming.

To fix it we need to add @objc(HomeViewController) at the top of your HomeViewController file.

Step5: Also to animate the presentation, we need to add animation code in viewWillAppear

See below reference code:

import UIKit

@objc(HomeViewController)

class HomeViewController : UINavigationController {

     init() {
        let viewController:UIViewController = UIStoryboard(name: "MainInterface", bundle: nil).instantiateViewController(withIdentifier: "MainPageViewController") as UIViewController
        super.init(rootViewController: viewController)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.view.transform = CGAffineTransform(translationX: 0, y: self.view.frame.size.height)

        UIView.animate(withDuration: 0.25, animations: { () -> Void in
            self.view.transform = CGAffineTransform.identity
        })
    }
}

Where MainPageViewController is the identifier of your MainViewController, which we want to present.

Step6: To dismiss with animation we can create new function in MainPageViewController class:

func hideExtensionWithCompletionHandler(completion:@escaping (Bool) -> Void) {
    UIView.animate(withDuration: 0.20, animations: {

        self.navigationController!.view.transform = CGAffineTransform(translationX: 0, y: self.navigationController!.view.frame.size.height)
    }, completion: completion)
}

call above func on Save or Cancel button and inside block, we can call completeRequest or cancelRequest(withError:)

func saveButtonTapped(sender: UIBarButtonItem) {
        self.hideExtensionWithCompletionHandler(completion: { (Bool) -> Void in
            self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil)
        })
    }

Now, Do whatever you want to do man, Do double man ;-)

Zoeb S
  • 695
  • 1
  • 7
  • 21