Exemple de base pour partager du texte ou une image avec UIActivityViewController dans Swift

132

J'ai commencé ma recherche en voulant savoir comment je pourrais partager avec d'autres applications sous iOS. J'ai découvert que deux manières importantes sont

  • UIActivityViewController
  • UIDocumentInteractionController

Ces méthodes et d'autres sont comparées dans cette réponse SO .

Souvent, lorsque j'apprends un nouveau concept, j'aime voir un exemple de base pour me lancer. Une fois que j'ai quelque chose de basique configuré, je peux le modifier comme je le souhaite plus tard.

Il y a beaucoup de questions SO liées à UIActivityViewController, mais je n'ai pas trouvé de questions qui demandaient juste un exemple simple. Puisque je viens d'apprendre comment faire cela, je vais fournir ma propre réponse ci-dessous. N'hésitez pas à en ajouter un meilleur (ou une version Objective-C).

Suragch
la source

Réponses:

279

Exemple de projet UIActivityViewController

Configurez votre storyboard avec deux boutons et connectez-les à votre contrôleur de vue (voir le code ci-dessous).

entrez la description de l'image ici

Ajoutez une image à vos Assets.xcassets. J'ai appelé le mien "lion".

entrez la description de l'image ici

Code

import UIKit
class ViewController: UIViewController {

    // share text
    @IBAction func shareTextButton(_ sender: UIButton) {

        // text to share
        let text = "This is some text that I want to share."

        // set up activity view controller
        let textToShare = [ text ]
        let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash

        // exclude some activity types from the list (optional)
        activityViewController.excludedActivityTypes = [ UIActivityType.airDrop, UIActivityType.postToFacebook ]

        // present the view controller
        self.present(activityViewController, animated: true, completion: nil)

    }

    // share image
    @IBAction func shareImageButton(_ sender: UIButton) {

        // image to share
        let image = UIImage(named: "Image")

        // set up activity view controller
        let imageToShare = [ image! ]
        let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash

        // exclude some activity types from the list (optional)
        activityViewController.excludedActivityTypes = [ UIActivityType.airDrop, UIActivityType.postToFacebook ]

        // present the view controller
        self.present(activityViewController, animated: true, completion: nil)
    }

}

Résultat

Cliquer sur "Partager du texte" donne le résultat à gauche et cliquer sur "Partager une image" donne le résultat à droite.

entrez la description de l'image ici

Remarques

  • J'ai retesté cela avec iOS 11 et Swift 4. J'ai dû l'exécuter plusieurs fois dans le simulateur avant que cela ne fonctionne car il expirait. Cela peut être dû au fait que mon ordinateur est lent.
  • Si vous souhaitez masquer certains de ces choix, vous pouvez le faire avec excludedActivityTypescomme indiqué dans le code ci-dessus.
  • Si vous n'incluez pas la popoverPresentationController?.sourceViewligne, votre application se bloquera lorsqu'elle sera exécutée sur un iPad.
  • Cela ne vous permet pas de partager du texte ou des images avec d'autres applications. Vous voulez probablement UIDocumentInteractionControllerpour ça.

Voir également

Suragch
la source
1
Pourquoi certains exemples montrent un tableau de 1 élément et certains en montre 2? En supposant partager une image.
Lim Thye Chean
@ Suragch: Salut, je veux partager un code de référence dans le texte et j'ai besoin que ce code soit copié en cliquant ou en appuyant sur comme cela se produit lorsque nous envoyons un numéro.
Ishika
74

Partager : Texte

@IBAction func shareOnlyText(_ sender: UIButton) {
    let text = "This is the text....."
    let textShare = [ text ]
    let activityViewController = UIActivityViewController(activityItems: textShare , applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
}
}

Partager : Image

@IBAction func shareOnlyImage(_ sender: UIButton) {
    let image = UIImage(named: "Product")
    let imageShare = [ image! ]
    let activityViewController = UIActivityViewController(activityItems: imageShare , applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
 }

Partager: Texte - Image - URL

   @IBAction func shareAll(_ sender: UIButton) {
    let text = "This is the text...."
    let image = UIImage(named: "Product")
    let myWebsite = NSURL(string:"https://stackoverflow.com/users/4600136/mr-javed-multani?tab=profile")
    let shareAll= [text , image! , myWebsite]
    let activityViewController = UIActivityViewController(activityItems: shareAll, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
   }

entrez la description de l'image ici

Monsieur Javed Multani
la source
4
hey ça ne marche pas. Dans FB, seul le lien est le partage, pas l'image et le texte.
Ekta Padaliya
@ScriptKitty. L'application de messagerie est-elle correctement configurée avec un compte i cloud?
Awais Fayyaz
1
@EktaPadaliya. Conformément à la politique de mise à jour FB, une URL ou une image peut être partagée. texte impossible
Awais Fayyaz
2
L'image @ Mr.JavedMultani n'est pas partagée dans WhatsApp
NickCoder
10

J'ai trouvé que cela fonctionnait parfaitement si vous souhaitez partager tout l'écran.

@IBAction func shareButton(_ sender: Any) {

    let bounds = UIScreen.main.bounds
    UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
    self.view.drawHierarchy(in: bounds, afterScreenUpdates: false)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    let activityViewController = UIActivityViewController(activityItems: [img!], applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view
    self.present(activityViewController, animated: true, completion: nil)
}
Cavalier Diavel
la source
9

À titre indicatif, vous pouvez également l'utiliser pour les iPad:

activityViewController.popoverPresentationController?.sourceView = sender

Ainsi, le popover sort de l'expéditeur (le bouton dans ce cas).

Adrien Brecheteau
la source
activityViewController.popoverPresentationController? .sourceView = expéditeur en tant que? UIView a fonctionné pour moi. :) merci
Brian
La boîte de partage n'était pas à venir pour les iPad. Cela a résolu les problèmes d'iPad que j'avais!
Asp Upload le
3

Vous pouvez utiliser les fonctions suivantes que j'ai écrites dans l'une de mes classes d'assistance dans un projet.

il suffit d'appeler

showShareActivity(msg:"message", image: nil, url: nil, sourceRect: nil) 

et cela fonctionnera à la fois pour iPhone et iPad. Si vous transmettez la valeur CGRect d'une vue par sourceRect, une petite flèche apparaîtra également sur l'iPad.

func topViewController()-> UIViewController{
    var topViewController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!

    while ((topViewController.presentedViewController) != nil) {
        topViewController = topViewController.presentedViewController!;
    }

    return topViewController
}

func showShareActivity(msg:String?, image:UIImage?, url:String?, sourceRect:CGRect?){
    var objectsToShare = [AnyObject]()

    if let url = url {
        objectsToShare = [url as AnyObject]
    }

    if let image = image {
        objectsToShare = [image as AnyObject]
    }

    if let msg = msg {
        objectsToShare = [msg as AnyObject]
    }

    let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityVC.modalPresentationStyle = .popover
    activityVC.popoverPresentationController?.sourceView = topViewController().view
    if let sourceRect = sourceRect {
        activityVC.popoverPresentationController?.sourceRect = sourceRect
    }

    topViewController().present(activityVC, animated: true, completion: nil)
}
Mahmud Ahsan
la source
Fonctionne parfaitement! 👍🏻
Ravindra_Bhati
Au lieu de la série d' ifinstructions, vous pouvez écrire [url, image, msg].compactMap({ $0 }).
Avi il y a
3

J'ai utilisé l'implémentation ci-dessus et je viens de savoir que cela ne fonctionne pas sur iPad sous iOS 13. J'ai dû ajouter ces lignes avant l'appel present () pour que cela fonctionne

//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
     popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
     popoverController.sourceView = self.view
     popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}

C'est comme ça que ça marche pour moi

func shareData(_ dataToShare: [Any]){

        let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)

        //exclude some activity types from the list (optional)
        //activityViewController.excludedActivityTypes = [
            //UIActivity.ActivityType.postToFacebook
        //]

        //avoiding to crash on iPad
        if let popoverController = activityViewController.popoverPresentationController {
            popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
            popoverController.sourceView = self.view
            popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
        }

        self.present(activityViewController, animated: true, completion: nil)
    }
Bréndal Teixeira
la source