LoginSignup
19
15

More than 3 years have passed since last update.

SwiftUIでViewを画像としてUIActivityを利用してSNSに共有する

Last updated at Posted at 2019-12-01

はじめに🍁

SwiftUIで特定のViewをSNSにシェアするtipsを共有します🍙

使いたかったLPLinkMetadata

iOS13から使えるようになったLPLinkMetadataを利用します。
これを
IMG_0373.JPG
↓のようにすることができます。
IMG_0372.JPG

UIActivityViewControllerをRepresentaぶる

UIActivityViewControllerをSwiftUIで扱えるようにします。

struct ShareSheet: UIViewControllerRepresentable {
    let photo: UIImage

    func makeUIViewController(context: Context) -> UIActivityViewController {
        let text = "🐥"
        let itemSource = ShareActivityItemSource(shareText: text, shareImage: photo)

        let activityItems: [Any] = [photo, text, itemSource]

        let controller = UIActivityViewController(
            activityItems: activityItems,
            applicationActivities: nil)

        return controller
    }

    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}

iOS13からのLPLinkMetadataを使う

import LinkPresentation

class ShareActivityItemSource: NSObject, UIActivityItemSource {

    var shareText: String
    var shareImage: UIImage
    var linkMetaData = LPLinkMetadata()

    init(shareText: String, shareImage: UIImage) {
        self.shareText = shareText
        self.shareImage = shareImage
        linkMetaData.title = shareText
        super.init()
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return UIImage(named: "AppIcon ") as Any
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        return nil
    }

    func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
        return linkMetaData
    }
}

ViewをUIViewに変換する

SwiftUI でViewをUIImageに変換する方法
前回書いた記事を参考にSwiftUIのViewをUIImageに変更する方法をご参照ください。

作成したShareSheetをモーダルで呼び出す

struct TestPage: View {
    @State private var rect: CGRect = .zero
    @State private var uiImage: UIImage? = nil
  // modalを表示するためのフラグを持つ
    @State private var showShareSheet = false

    var body: some View {
        VStack {
            HStack {
                Image(systemName: "sun.haze")
                    .font(.title)
                    .foregroundColor(.white)
                Text("Hello, World!")
                    .font(.title)
                    .foregroundColor(.white)
            }
            .padding()
            .background(Color.blue)
            .cornerRadius(8)
            .background(RectangleGetter(rect: $rect))
            .onAppear() {

            }

            Button(action: {
                self.uiImage = UIApplication.shared.windows[0].rootViewController?.view!.getImage(rect: self.rect)
                self.showShareSheet.toggle()
            }) {
                Image(systemName: "square.and.arrow.up")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 50, height: 50)
                    .padding()
                    .background(Color.pink)
                    .foregroundColor(Color.white)
                    .mask(Circle())
            }.sheet(isPresented: self.$showShareSheet) {
              // 共有したいUIImageを渡す
                ShareSheet(photo: self.uiImage!)
            }.padding()
        }
    }
}

結果

IMG_0374.JPG

ちゃんとツイートできました!

全体のコード

19
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
15