Do it! 스위프트로 아이폰 앱 만들기
15장 카메라와 포토 라이브러리에서 미디어 가져오기
- 빈 스토리보드에 Horizontal Stack View 배치하기
- [Add New Constraints] 에서
위:0, 왼쪽:16, 오른쪽:16, 아래:0 으로 설정하기- 세로 스택 뷰 안에 Image View 배치하기
- Content Mode: [Aspect Fit]
- Background: [System grouped Background Color]
- 이미지 뷰 아래에 2개의 Vertical Stack View 배치하기
- 각 가로 스택 뷰 안에 버튼 2개씩 배치하기
- 가로 스택 뷰 2개를 선택하고 [Attributes inspector] -> [Distribution] -> [Fill Equally] 설정하기
- 스택 뷰 내에 있는 객체들의 크기가 모두 동일하게 맞춰진다.
- 버튼 4개를 선택하고 [Add New Constraints] -> Height = 40 으로 설정하기
- 버튼명 수정하기
import UIKit
import MobileCoreServices
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let imagePicker: UIImagePickerController! = UIImagePickerController()
var captureImage: UIImage!
var videoURL: URL!
var flagImageSave = false
- 카메라와 포토 라이브러리를 사용하기 위해 필요한 것
- ImagePickerController
- 위 컨트롤러를 사용하기 위한 델리게이트 프로토콜
- 미디어 타입이 정의된 헤더 파일
func myAlert(_ title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
경고 표시용 메소드
@IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
사진 촬영 버튼 코드
- 카메라 사용 가능 여부 확인
- 이미지 저장 허용
- 편집 불가
@IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
}
}
사진 불러오기 버튼 코드
- 포토 라이브러리 사용 가능 여부 확인
- 이미지 저장 불가
- 편집 허용
@IBAction func btnRecordVideoFromCamera(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
비디오 촬영 버튼 코드
- 카메라 사용 가능 여부 확인
- 비디오 저장 허용
- 편집 불가
@IBAction func btnLoadVideoFromLibrary(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
}
}
비디오 불러오기 버튼 코드
- 포토 라이브러리 사용 가능 여부 확인
- 비디오 저장 불가
- 편집 불가
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
if flagImageSave {
UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
}
imgView.image = captureImage
}
else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
if flagImageSave {
videoURL = (info[UIImagePickerController.InfoKey.mediaURL] as! URL)
UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)
}
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
델리게이트 메소드 코드
- 카메라 촬영이 끝나거나 포토 라이브러리에서 선택이 끝났을 때 호출된다.
- flagImageSave 값에 따라 포토 라이브러리에 미디어 저장하기
- 마지막에 이미지 피커 컨트롤러를 제거하여 초기 뷰 보여주기
- 촬영을 하지 않거나 포토 라이브러리에서 선택하지 않고 취소했을 경우에는 이미지 피커 컨트롤러 제거하기
💡 시뮬레이터에서는 카메라 테스트 불가
import UIKit
import MobileCoreServices
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let imagePicker: UIImagePickerController! = UIImagePickerController()
var captureImage: UIImage!
var videoURL: URL!
var flagImageSave = false
@IBOutlet var imgView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
@IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
}
}
@IBAction func btnRecordVideoFromCamera(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
@IBAction func btnLoadVideoFromLibrary(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
if flagImageSave {
UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
}
imgView.image = captureImage
}
else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
if flagImageSave {
videoURL = (info[UIImagePickerController.InfoKey.mediaURL] as! URL)
UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)
}
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func myAlert(_ title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
}
import UIKit
import MobileCoreServices
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let imagePicker: UIImagePickerController! = UIImagePickerController()
var captureImage: UIImage!
var flagImageSave = false
var numImage = 0
@IBOutlet var imgView1: UIImageView!
@IBOutlet var imgView2: UIImageView!
@IBOutlet var imgView3: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func btnCaptureImageFromCamera(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
numImage += 1
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
@IBAction func btnLoadImageFromLibrary(_ sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
numImage += 1
}
else {
myAlert("Photo album inaccessible", message: "Application cannot access the photo album.")
}
}
@IBAction func initImageView(_ sender: UIButton) {
imgView1.image = nil
imgView2.image = nil
imgView3.image = nil
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
if flagImageSave {
UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
}
switch numImage {
case 1:
imgView1.image = captureImage
break
case 2:
imgView2.image = captureImage
break
case 3:
imgView3.image = captureImage
break
default:
break
}
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
numImage -= 1
self.dismiss(animated: true, completion: nil)
}
func myAlert(_ title:String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let action = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
}