Ejemplo básico para compartir texto o imagen con UIActivityViewController en Swift

130

Comencé mi búsqueda queriendo saber cómo podría compartir con otras aplicaciones en iOS. Descubrí que hay dos formas importantes

  • UIActivityViewController
  • UIDocumentInteractionController

Estos y otros métodos se comparan en esta respuesta SO .

A menudo, cuando estoy aprendiendo un nuevo concepto, me gusta ver un ejemplo básico para comenzar. Una vez que obtengo una configuración básica, puedo modificarla como más tarde me guste.

Hay muchas preguntas SO relacionadas UIActivityViewController, pero no pude encontrar ninguna que solo pidiera un ejemplo simple. Como acabo de aprender a hacer esto, proporcionaré mi propia respuesta a continuación. Siéntase libre de agregar una mejor (o una versión de Objective-C).

Suragch
fuente

Respuestas:

278

Proyecto de ejemplo UIActivityViewController

Configure su guión gráfico con dos botones y conéctelos a su controlador de vista (vea el código a continuación).

ingrese la descripción de la imagen aquí

Agregue una imagen a sus Assets.xcassets. Yo llamé al mío "león".

ingrese la descripción de la imagen aquí

Código

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)
    }

}

Resultado

Al hacer clic en "Compartir texto" se obtiene el resultado a la izquierda y al hacer clic en "Compartir una imagen" se obtiene el resultado a la derecha.

ingrese la descripción de la imagen aquí

Notas

  • Volví a probar esto con iOS 11 y Swift 4. Tuve que ejecutarlo un par de veces en el simulador antes de que funcionara porque se estaba agotando el tiempo de espera. Esto puede deberse a que mi computadora es lenta.
  • Si desea ocultar algunas de estas opciones, puede hacerlo excludedActivityTypescomo se muestra en el código anterior.
  • Si no se incluye la popoverPresentationController?.sourceViewlínea, la aplicación se bloqueará cuando se ejecute en un iPad.
  • Esto no le permite compartir texto o imágenes a otras aplicaciones. Probablemente quieras UIDocumentInteractionControllerpara eso.

Ver también

Suragch
fuente
1
¿Por qué algunos ejemplos muestran una matriz de 1 elemento y algunos muestran 2? Asumiendo compartir una imagen.
Lim Thye Chean
@ Suragch: Hola, quiero compartir un código de referencia en el texto y necesito que ese código se copie al hacer clic o tocar como sucede cuando enviamos un número.
Ishika
73

Compartir: texto

@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)
}
}

Compartir: Imagen

@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)
 }

Compartir: Texto - Imagen - 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)
   }

ingrese la descripción de la imagen aquí

Sr. Javed Multani
fuente
44
oye, no funciona. En FB solo el enlace es compartir, no imagen y texto.
Ekta Padaliya
@ScriptKitty. ¿La aplicación de mensajes está configurada correctamente con una cuenta de i cloud?
Awais Fayyaz
1
@EktaPadaliya. De acuerdo con la política de actualización de FB, se puede compartir una URL o una imagen. texto no puede
Awais Fayyaz
medium.com/@javedmultani16/…
Mr.Javed Multani el
2
@ Mr.JavedMultani la imagen no se comparte en
WhatsApp
10

Encontré que esto funciona a la perfección si quieres compartir toda la pantalla.

@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)
}
Jinete de Diavel
fuente
9

Solo como nota, también puede usar esto para iPads:

activityViewController.popoverPresentationController?.sourceView = sender

Entonces el popover aparece del remitente (el botón en ese caso).

Adrien Brecheteau
fuente
activityViewController.popoverPresentationController? .sourceView = remitente como? UIView funcionó para mí. :) gracias
Brian
El cuadro Compartir no aparecía para iPads. ¡Esto solucionó los problemas de iPad que estaba teniendo!
Asp Upload
3

Puede usar las siguientes funciones que escribí en una de mis clases de ayuda en un proyecto.

solo llama

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

y funcionará tanto para iPhone como para iPad. Si pasa el valor CGRect de cualquier vista por sourceRect, también mostrará una pequeña flecha en el 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
fuente
Funciona perfecto! 👍🏻
Ravindra_Bhati
3

Utilicé la implementación anterior y justo ahora me di cuenta de que no funciona en iPad con iOS 13. Tuve que agregar estas líneas antes de la llamada present () para que funcione

//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)
}

Así funciona para mí

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
fuente