MontgommeryJR
MontgommeryJR

Reputation: 275

Trying to make a screenshot button that sends the screenshot to my camera roll, when the button is clicked. Swift 3, Xcode 8, IOS

Swift 3, Xcode 8, IOS:

I can't seem to figure out what I'm doing wrong, no errors show up, but when I click the button in my app, nothing happens and nothing is saved in my simulators camera roll.

This is what I've done for the button in the view controller:

import UIKit
class ViewController: ViewController {

override func viewDidLoad() { 
    super.viewDidLoad() 
}

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
}

@IBAction func buttonAction(_ sender: UIButton) {
    func captureScreen() {

        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
    }
}
}

Upvotes: 2

Views: 3364

Answers (2)

Jayce
Jayce

Reputation: 427

In Swift 3.1

First you need to edit your info.plist file enter image description here

import Photos        

then add the uibutton:

@IBOutlet weak var shutterButton: UIButton!



@IBAction func shotAction(_ sender: Any) {
    guard shutterButton.isEnabled else {
        return
    }

    let takeScreenshotBlock = {
        //Render and capture an UIView named view:
        self.shutterButton.isHidden = true
        UIGraphicsBeginImageContextWithOptions(self.view.frame.size, false, 0.0)
        self.view.drawHierarchy(in: self.view.frame, afterScreenUpdates: true)
        if let image = UIGraphicsGetImageFromCurrentImageContext() {
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        }
        UIGraphicsEndImageContext();
        self.shutterButton.isHidden = false


        DispatchQueue.main.async {
            // briefly flash the screen
            let flashOverlay = UIView(frame: self.sceneView.frame)
            flashOverlay.backgroundColor = UIColor.white
            self.sceneView.addSubview(flashOverlay)
            UIView.animate(withDuration: 0.25, animations: {
                flashOverlay.alpha = 0.0
            }, completion: { _ in
                flashOverlay.removeFromSuperview()
            })
        }
    }
    switch PHPhotoLibrary.authorizationStatus() {
    case .authorized:
        takeScreenshotBlock()
    case .restricted, .denied:
        let alertController = UIAlertController(title: "Photo access denied", message: "Please enable Photos Library access for this appliction in Settings > Privacy.", preferredStyle: UIAlertControllerStyle.alert)
        let actionOK = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alertController.addAction(actionOK)
        present(alertController, animated: true, completion: nil)
    case .notDetermined:
        PHPhotoLibrary.requestAuthorization({ (status) in
            if status == .authorized {
                takeScreenshotBlock()
            }
        })
    }
}

Upvotes: 1

Nirav D
Nirav D

Reputation: 72440

The problem is you have put screenshot taking code inside nested function of your buttonAction method name captureScreen and never called that method, there is no need to add nested method. So simply remove that function and put the screenshot code directly inside the button action method. So replace your button action with this one.

@IBAction func buttonAction(_ sender: UIButton) {

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
    view.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)        
}

Upvotes: 4

Related Questions