Базовый пример совместного использования текста или изображения с UIActivityViewController в Swift

132

Я начал свой поиск с того, что хотел узнать, как я могу поделиться с другими приложениями в iOS. Я обнаружил, что два важных способа

  • UIActivityViewController
  • UIDocumentInteractionController

Эти и другие методы сравниваются в этом SO-ответе .

Часто, когда я изучаю новую концепцию, мне нравится видеть простой пример, чтобы начать работу. Как только я получу что-то базовое, я могу изменить его, как мне нравится, позже.

Есть много вопросов, связанных с SO UIActivityViewController, но я не мог найти ни одного, который просто просил бы простой пример. Поскольку я только что научился это делать, я дам свой ответ ниже. Не стесняйтесь добавлять лучшую версию (или версию Objective-C).

Suragch
источник

Ответы:

279

Пример проекта UIActivityViewController

Настройте раскадровку с двумя кнопками и подключите их к контроллеру представления (см. Код ниже).

введите описание изображения здесь

Добавьте изображение в свой Assets.xcassets. Я назвал свой «лев».

введите описание изображения здесь

Код

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

}

результат

Нажатие «Поделиться текстом» дает результат слева, а нажатие «Поделиться изображением» дает результат справа.

введите описание изображения здесь

Ноты

  • Я повторно протестировал это с iOS 11 и Swift 4. Мне пришлось запустить его пару раз в симуляторе, прежде чем он заработал, потому что время ожидания истекло. Это может быть потому, что мой компьютер работает медленно.
  • Если вы хотите скрыть некоторые из этих вариантов, вы можете сделать это, excludedActivityTypesкак показано в приведенном выше коде.
  • Отсутствие popoverPresentationController?.sourceViewстроки приведет к сбою вашего приложения при запуске на iPad.
  • Это не позволяет вам делиться текстом или изображениями с другими приложениями. Вы, наверное, этого захотите UIDocumentInteractionController.

Смотрите также

Suragch
источник
1
Почему в некоторых примерах показан массив из 1 элемента, а в некоторых - 2? Предполагая, что вы поделитесь изображением.
Лим Тай Чин
@ Suragch: Привет, я хочу поделиться кодом ссылки в тексте и мне нужно, чтобы этот код копировался при нажатии или касании, как это происходит, когда мы отправляем номер.
Ishika
75

Поделиться: Текст

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

Поделиться: Изображение

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

Поделиться: Текст - Изображение - 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)
   }

введите описание изображения здесь

Г-н Джавед Мултани
источник
4
эй, это не работает. В FB делится только ссылка, а не изображение и текст.
Ekta Padaliya
@ScriptKitty. Правильно ли настроено приложение сообщений с облачной учетной записью i?
Awais Fayyaz
1
@EktaPadaliya. Согласно политике обновления FB, можно делиться либо URL-адресом, либо изображением. текст не может
Awais Fayyaz
medium.com/@javedmultani16/...
Mr.Javed Мултани
2
Изображение @ Mr.JavedMultani не используется в WhatsApp
NickCoder,
10

В качестве примечания вы также можете использовать это для iPad:

activityViewController.popoverPresentationController?.sourceView = sender

Итак, всплывающее окно появляется у отправителя (в данном случае кнопка).

Адриан Брешето
источник
activityViewController.popoverPresentationController? .sourceView = отправитель как? UIView -работал у меня. :) спасибо
Брайан
Коробка «Поделиться» не предназначалась для iPad. Это устранило проблемы с iPad, которые у меня были!
Asp Загрузить
10

Я обнаружил, что это работает безупречно, если вы хотите показать весь экран.

@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
источник
3

Вы можете использовать следующие функции, которые я написал в одном из моих вспомогательных классов в проекте.

просто позвони

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

и он будет работать как на iPhone, так и на iPad. Если вы передадите значение CGRect любого представления с помощью sourceRect, оно также отобразит маленькую стрелку на 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)
}
Махмуд Ахсан
источник
Отлично работает! 👍🏻
Ravindra_Bhati
Вместо серии ifутверждений можно писать [url, image, msg].compactMap({ $0 }).
Ави
3

Я использовал приведенную выше реализацию и только сейчас узнал, что она не работает на iPad под управлением iOS 13. Мне пришлось добавить эти строки перед вызовом present (), чтобы заставить его работать.

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

Вот как это работает для меня

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)
    }
Брендаль Тейшейра
источник