Exemplo básico para compartilhar texto ou imagem com o UIActivityViewController no Swift

130

Comecei minha pesquisa querendo saber como compartilhar com outros aplicativos no iOS. Eu descobri que duas maneiras importantes são

  • UIActivityViewController
  • UIDocumentInteractionController

Esses e outros métodos são comparados nesta resposta SO .

Muitas vezes, quando estou aprendendo um novo conceito, gosto de ver um exemplo básico para começar. Depois de obter algo básico, posso modificá-lo como quiser mais tarde.

Existem muitas perguntas relacionadas ao SO UIActivityViewController, mas não consegui encontrar nenhuma que estivesse apenas pedindo um exemplo simples. Desde que aprendi a fazer isso, fornecerei minha própria resposta abaixo. Sinta-se à vontade para adicionar uma versão melhor (ou uma versão do Objective-C).

Suragch
fonte

Respostas:

278

Projeto de exemplo UIActivityViewController

Configure seu storyboard com dois botões e conecte-os ao seu controlador de exibição (veja o código abaixo).

insira a descrição da imagem aqui

Adicione uma imagem aos seus Assets.xcassets. Eu chamei o meu "leão".

insira a descrição da imagem aqui

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

Clicar em "Compartilhar texto" fornece o resultado à esquerda e clicar em "Compartilhar uma imagem" mostra o resultado à direita.

insira a descrição da imagem aqui

Notas

  • Testei isso novamente com o iOS 11 e o Swift 4. Tive que executá-lo algumas vezes no simulador antes de funcionar porque estava chegando ao tempo limite. Isso pode ocorrer porque meu computador está lento.
  • Se você deseja ocultar algumas dessas opções, faça isso excludedActivityTypesconforme mostrado no código acima.
  • Não incluir a popoverPresentationController?.sourceViewlinha fará com que seu aplicativo falhe quando executado em um iPad.
  • Isso não permite que você compartilhe texto ou imagens com outros aplicativos. Você provavelmente quer UIDocumentInteractionControllerisso.

Veja também

Suragch
fonte
1
Por que alguns exemplos mostram a matriz de 1 item e alguns mostram 2? Supondo que você compartilhe uma imagem.
Lim Thye Chean
@ Suragch: Oi, eu quero compartilhar um código de referência no texto e preciso que esse código seja copiado ao clicar ou tocar em como acontece quando enviamos um número.
Ishika
73

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

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

Compartilhar: Texto - Imagem - 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)
   }

insira a descrição da imagem aqui

Mr.Javed Multani
fonte
4
Ei, não está funcionando. No FB, apenas o link não é compartilhar imagem e texto.
Ekta Padaliya
@ScriptKitty. O aplicativo de mensagens está configurado corretamente com uma conta na nuvem i?
Awais Fayyaz
1
@EktaPadaliya. De acordo com a política de atualização do FB, é possível compartilhar um URL ou uma imagem. o texto não pode
Awais Fayyaz 11/11
Você está aqui
Página Inicial
2
@ Mr.JavedMultani imagem não é compartilhada no whatsapp
NickCoder
10

Achei que isso funcionaria perfeitamente se você quiser compartilhar a tela inteira.

@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)
}
Diavel Rider
fonte
9

Apenas como nota, você também pode usar isso para iPads:

activityViewController.popoverPresentationController?.sourceView = sender

Portanto, a popover aparece no remetente (o botão nesse caso).

Adrien Brecheteau
fonte
activityViewController.popoverPresentationController? .sourceView = remetente como? O UIView funcionou para mim. :) obrigado
Brian
A caixa Compartilhar não estava aparecendo para iPads. Isso corrigiu os problemas do iPad que eu estava tendo!
Asp Upload
3

Você pode usar as seguintes funções que escrevi em uma das minhas aulas auxiliares em um projeto.

apenas ligue

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

e funcionará para iPhone e iPad. Se você passar o valor CGRect de qualquer modo de exibição por sourceRect, ele também mostrará uma pequena seta no 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
fonte
Works Perfect! --🏻
Ravindra_Bhati
3

Eu usei a implementação acima e agora soube que ela não funciona no iPad com iOS 13. Eu tinha que adicionar essas linhas antes da chamada present () para fazê-la funcionar

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

É assim que funciona para mim

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
fonte