[swift] PeekPop을 활용한 카메라 앱의 찍은 사진 미리보기 기능 구현 방법

이번에는 Swift 언어를 사용하여 카메라 앱에서 찍은 사진을 미리보기하는 기능을 구현하는 방법을 살펴보겠습니다. 이 기능은 PeekPop을 활용하여 3D Touch 기능을 이용하여 사진을 미리 볼 수 있는 기능입니다.

1. 미리보기를 위한 준비 작업

먼저, 카메라 앱에서 사진을 찍은 후에 해당 사진을 미리보기로 보여주기 위해, 사진을 저장하는 과정을 구현해야 합니다. 이 과정을 위해 PhotoKit 프레임워크를 사용하여 사진을 저장하고, 저장된 사진의 URL을 저장해야 합니다.

import UIKit
import Photos

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    var imagePicker: UIImagePickerController!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 카메라 앱에서 사진 찍기를 위한 이미지 피커 설정
        imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
    }
    
    // 사진 찍기 버튼을 눌렀을 때의 액션
    @IBAction func takePhotoButtonPressed(_ sender: UIButton) {
        present(imagePicker, animated: true, completion: nil)
    }
    
    // 이미지를 선택하거나 찍은 후에 호출되는 메서드
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 사진을 저장
        guard let image = info[.originalImage] as? UIImage else {
            return
        }
        PHPhotoLibrary.shared().performChanges({
            PHAssetChangeRequest.creationRequestForAsset(from: image)
        }) { (success, error) in
            if success {
                // 저장된 사진의 URL을 얻어온 후에 미리보기 뷰로 이동
                PHAsset.fetchAssets(with: .image, options: nil).lastObject?.requestContentEditingInput(with: nil, completionHandler: { (input, _) in
                    guard let input = input else {
                        return
                    }
                    DispatchQueue.main.async {
                        let previewViewController = PreviewViewController(input: input)
                        self.navigationController?.pushViewController(previewViewController, animated: true)
                    }
                })
            }
        }
        picker.dismiss(animated: true, completion: nil)
    }
}

2. 미리보기 뷰 컨트롤러 구현

앞서 저장한 사진의 URL을 이용하여 미리보기 뷰 컨트롤러를 구현해야 합니다. 이 뷰 컨트롤러는 PeekPop을 활용하여 미리보기 기능을 제공합니다.

import UIKit
import PhotosUI

class PreviewViewController: UIViewController {

    var asset: PHAsset?
    var input: PHContentEditingInput?
    var previewView: PHLivePhotoView!

    convenience init(input: PHContentEditingInput) {
        self.init(nibName: nil, bundle: nil)
        self.input = input
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 미리보기 화면 구성
        previewView = PHLivePhotoView(frame: view.bounds)
        view.addSubview(previewView)
        
        // 저장된 사진의 URL을 이용하여 미리보기 화면에 표시
        asset = input?.fullSizeImageURL.flatMap { try? PHAsset.fetchAssets(withALAssetURLs: [$0], options: nil).firstObject() }
        PHImageManager.default().requestLivePhoto(for: asset!, targetSize: view.bounds.size, contentMode: .aspectFit, options: nil) { (livePhoto, _) in
            DispatchQueue.main.async {
                self.previewView.livePhoto = livePhoto
                self.previewView.startPlayback(with: .hint)
            }
        }
    }
}

3. PeekPop 기능 활용

미리보기 기능을 위해서는 PeekPop을 활용해야 합니다. PeekPop은 3D Touch가 지원되는 디바이스에서 뷰 컨트롤러를 미리 조회하고 미리보기를 제공하는 기능을 제공합니다. 따라서 PeekPop 클래스를 사용하여 해당 기능을 구현할 수 있습니다.

import UIKit
import PeekPop

class ViewController: UIViewController, PeekPopPreviewingDelegate {
    
    var imagePicker: UIImagePickerController!
    var peekPop: PeekPop?

    override func viewDidLoad() {
        super.viewDidLoad()
        // PeekPop 초기화
        peekPop = PeekPop(viewController: self)
        peekPop?.registerForPreviewingWithDelegate(self, sourceView: view)
        
        // 카메라 앱에서 사진 찍기를 위한 이미지 피커 설정
        imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
    }
    
    // 사진 찍기 버튼을 눌렀을 때의 액션
    @IBAction func takePhotoButtonPressed(_ sender: UIButton) {
        present(imagePicker, animated: true, completion: nil)
    }
    
    // 이미지를 선택하거나 찍은 후에 호출되는 메서드
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 사진을 저장
        ...
    }
    
    // MARK: - PeekPopPreviewingDelegate
    
    func previewingContext(_ previewingContext: PreviewingContext, viewControllerForLocation location: CGPoint) -> UIViewController? {
        // 미리보기 뷰 컨트롤러를 반환
        let previewViewController = PreviewViewController(input: input!)
        return previewViewController
    }
    
    func previewingContext(_ previewingContext: PreviewingContext, commitViewController viewControllerToCommit: UIViewController) {
        // 미리보기 뷰 컨트롤러로 전환
        navigationController?.pushViewController(viewControllerToCommit, animated: true)
    }
}

위의 코드를 참고하여, PeekPop을 활용하여 카메라 앱의 사진 미리보기 기능을 구현해보세요. 이를 통해 사용자들은 사진을 찍은 후 빠르게 미리보기를 확인할 수 있게 될 것입니다.