Grundlegendes Beispiel für die Freigabe von Text oder Bild mit UIActivityViewController in Swift

130

Ich habe meine Suche gestartet, indem ich wissen wollte, wie ich sie für andere Apps in iOS freigeben kann. Ich entdeckte, dass zwei wichtige Wege sind

  • UIActivityViewController
  • UIDocumentInteractionController

Diese und andere Methoden werden in dieser SO-Antwort verglichen .

Wenn ich ein neues Konzept lerne, sehe ich oft ein einfaches Beispiel, um mich anzufangen. Sobald ich etwas Grundlegendes eingerichtet habe, kann ich es später nach Belieben ändern.

Es gibt viele SO-Fragen UIActivityViewController, aber ich konnte keine finden, die nur nach einem einfachen Beispiel fragten. Da ich gerade gelernt habe, wie das geht, werde ich unten meine eigene Antwort geben. Fühlen Sie sich frei, eine bessere (oder eine Objective-C-Version) hinzuzufügen.

Suragch
quelle

Antworten:

278

UIActivityViewController-Beispielprojekt

Richten Sie Ihr Storyboard mit zwei Schaltflächen ein und schließen Sie sie an Ihren View Controller an (siehe Code unten).

Geben Sie hier die Bildbeschreibung ein

Fügen Sie Ihren Assets.xcassets ein Bild hinzu. Ich nannte meinen "Löwen".

Geben Sie hier die Bildbeschreibung ein

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

}

Ergebnis

Wenn Sie links auf "Text freigeben" klicken, wird links das Ergebnis angezeigt, und wenn Sie auf "Bild freigeben" klicken, wird rechts das Ergebnis angezeigt.

Geben Sie hier die Bildbeschreibung ein

Anmerkungen

  • Ich habe dies mit iOS 11 und Swift 4 erneut getestet. Ich musste es einige Male im Simulator ausführen, bevor es funktionierte, weil es eine Zeitüberschreitung gab. Dies kann daran liegen, dass mein Computer langsam ist.
  • Wenn Sie einige dieser Optionen ausblenden möchten, können Sie dies excludedActivityTypeswie im obigen Code gezeigt tun .
  • popoverPresentationController?.sourceViewWenn Sie die Zeile nicht einschließen , stürzt Ihre App ab, wenn sie auf einem iPad ausgeführt wird.
  • Auf diese Weise können Sie keinen Text oder Bilder für andere Apps freigeben. Sie wollen wahrscheinlich UIDocumentInteractionControllerdafür.

Siehe auch

Suragch
quelle
1
Warum zeigen einige Beispiele ein Array von 1 Element und einige zeigen 2? Angenommen, Sie teilen ein Bild.
Lim Thye Chean
@ Suragch: Hallo, ich möchte einen Referenzcode im Text freigeben und muss diesen Code beim Klicken oder Tippen kopieren, wie es passiert, wenn wir eine Nummer senden.
Ishika
73

Teilen: Text

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

Teilen: Bild

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

Teilen: Text - Bild - 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)
   }

Geben Sie hier die Bildbeschreibung ein

Mr.Javed Multani
quelle
4
Hey, es funktioniert nicht. In FB ist nur Link teilen, nicht Bild und Text.
Ekta Padaliya
@ScriptKitty. Ist die Nachrichten-App mit einem i Cloud-Konto richtig konfiguriert?
Awais Fayyaz
1
@EktaPadaliya. Gemäß der FB-Aktualisierungsrichtlinie kann entweder eine URL oder ein Bild freigegeben werden. Text kann nicht
Awais Fayyaz
2
@ Mr.JavedMultani Bild wird nicht in WhatsApp geteilt
NickCoder
10

Ich fand, dass dies einwandfrei funktioniert, wenn Sie den gesamten Bildschirm freigeben möchten.

@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
quelle
9

Nur als Hinweis können Sie dies auch für iPads verwenden:

activityViewController.popoverPresentationController?.sourceView = sender

Das Popover wird also vom Absender angezeigt (in diesem Fall die Schaltfläche).

Adrien Brecheteau
quelle
activityViewController.popoverPresentationController? .sourceView = Absender als? UIView - für mich gearbeitet. :) danke
Brian
Die Share-Box wurde für iPads nicht angezeigt. Dies hat die iPad-Probleme behoben, die ich hatte!
Asp Upload
3

Sie können die folgenden Funktionen verwenden, die ich in einer meiner Hilfsklassen in einem Projekt geschrieben habe.

Ruf einfach an

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

und es wird sowohl für iPhone als auch für iPad funktionieren. Wenn Sie den CGRect-Wert einer Ansicht an sourceRect übergeben, wird auf dem iPad auch ein kleiner Pfeil angezeigt.

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
quelle
Funktioniert perfekt! 👍🏻
Ravindra_Bhati
3

Ich habe die obige Implementierung verwendet und gerade erfahren, dass sie auf einem iPad mit iOS 13 nicht funktioniert. Ich musste diese Zeilen vor dem Aufruf von present () hinzufügen, damit sie funktionieren

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

So funktioniert das bei mir

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
quelle