0

I am creating QR code in swift and assigning it to an imageView

when I try to share that image with generated code, it does not shares that image,

func createCode()
{
    let text = email

    let data = text.data(using: .ascii, allowLossyConversion: false)
    fillter = CIFilter(name: "CIQRCodeGenerator")
    fillter.setValue(data, forKey: "inputMessage")
    let transform = CGAffineTransform(scaleX: 5.0, y: 5.0)

    CreatedImage = UIImage(ciImage: (fillter.outputImage?.transformed(by: transform))!)

    imageCode.image = CreatedImage as UIImage
}

and this is share button

@IBAction func shareButtonPressed(_ sender: Any)
{

    let activityItem: [UIImage] = [imageCode.image!]

    let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])

    activity.popoverPresentationController?.sourceView  = self.view
    self.present(activity, animated: true, completion: nil)

}

it shows like it has nothing to share, it does not pick any bit of image

Arasuvel
  • 2,971
  • 1
  • 25
  • 40
Shahbaz Ali
  • 603
  • 1
  • 8
  • 15
  • I think its help you! https://stackoverflow.com/questions/40443957/sending-an-on-the-fly-created-qr-code-uiimage-by-airdrop-fails – Pavel S Apr 22 '19 at 19:11
  • Solution is to render image in UIImage view - find more here https://stackoverflow.com/questions/57526584/uiimageview-content-is-not-shared/57537702#57537702 – Dawy Aug 17 '19 at 15:44

3 Answers3

0

Have you created a variable to store the image somewhere e.g.

var generatedImage: UIImage?

Assuming then, that I have read your question correctly, in your creation function you can cast the image at the end of the function e.g:

generatedImage = imageCode.image

Then in your share function you could say:

   guard let validQR = generatedImage else { return }

    let activityItem: [UIImage] = [validQR]

    let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])

    activity.popoverPresentationController?.sourceView  = self.view
    self.present(activity, animated: true, completion: nil)

I tested with an image from my Bundle e.g:

 generatedImage = UIImage(named: "SCNPyramid")

And I was able to share the image :)

BlackMirrorz
  • 7,217
  • 2
  • 20
  • 31
0

after searching all..

I cam I to know that make a programmatically screen shot of desired view, that is sent..

Shahbaz Ali
  • 603
  • 1
  • 8
  • 15
0

I have been having the same problem and solved it by first saving the generated qr code image to a file and then sharing the file url.

private func shareQRCode() {
    guard let qrcode = self.qrCodeImage,
          let data = qrcode.pngData(),
          let url = self.saveInCache(data: data, fileName: "QRCode.png") else { return }
    
    // set up activity view controller
    let imageToShare = [url]
    let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash

    // work around to prevent dismissing current view after saving image
    let tempController = TransparentViewController()
    tempController.modalPresentationStyle = .overFullScreen

    activityViewController.completionWithItemsHandler = { [weak tempController] _, _, _, _ in
      if let presentingViewController = tempController?.presentingViewController {
        presentingViewController.dismiss(animated: false, completion: nil)
      } else {
        tempController?.dismiss(animated: false, completion: nil)
      }
    }

    present(tempController, animated: true) { [weak tempController] in
        tempController?.present(activityViewController, animated: true, completion: nil)
    }
}

Here is the code for saveInCache function:

private func saveInCache(data: Data, fileName: String) -> URL? {
    let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
    let path = paths[0]
    let fileUrl = path.appendingPathComponent(fileName)
    
    let fileManager = FileManager.default
    
    if self.pathExists(fileUrl) {
        do {
            try fileManager.removeItem(at: fileUrl)
        
        } catch { return fileUrl }
    }
    
    guard fileManager.createFile(atPath: fileUrl.path, contents: data, attributes: nil) else {
        return nil
    }
    
    return fileUrl
}

private func pathExists(_ path: URL) -> Bool {
    let fileManager = FileManager.default
    var isDir: ObjCBool = false
    
    if fileManager.fileExists(atPath: path.path, isDirectory: &isDir) {
        if isDir.boolValue {
            // file exists and is a directory
            return true
            
        } else {
            // file exists and is not a directory
            return true
        }
    } else {
        // file does not exist
        return false
    }
}

And here a simple Transparent View Controller for ActivityViewController work around:

final class TransparentViewController: UIViewController {

    override func viewDidLoad() {
        self.view.backgroundColor = .clear
    }
}
sciasxp
  • 1,031
  • 10
  • 12