실행 결과
버튼을 통해서 이미지를 추가하고 추가한 이미지를 화면에 띄워준다.
레이아웃
상단에 네비게이션 바를 추가해 주고, add형식의 바버튼을 추가해 준다.
화면 중앙에는 UIImageView를 추가한다.
아웃렛 변수 및 액션 함수 추가
1. 선택한 이미지 뷰를 출력해 주기 위해 이미지 뷰의 아웃렛 변수 연결한다.
2. 버튼을 통해 이미지 추가 동작을 실행할 것이므로 버튼에 액션 함수를 연결한다.
Add 버튼
@IBAction func addBtnClick(_ sender:UIButton){
let alert = UIAlertController(title: "Title", message: "message", preferredStyle: .actionSheet)
let library = UIAlertAction(title: "앨범에서 가져오기", style: .default) { (action) in self.openLibrary() }
let camera = UIAlertAction(title: "카메라", style: .default) { (action) in self.openCamera() }
let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil)
alert.addAction(library)
alert.addAction(camera)
alert.addAction(cancel)
present(alert, animated: true, completion: nil)
}
add 버튼을 눌렀을 때 카메라에 들어갈지 앨범에 들어갈지 선택하게 선택하는 actionSheet를 생성한다.
UIAlertController의 preferredStyle을 actionSheet로 선택해 actionSheet 알림 창을 생성한다.
생성되는 버튼은 카메라, 앨범에서 가져오기 두 가지이므로 두 가지의 UIAlertAction을 생성하고 각각의 함수를 연결해 준다.
openLibrary()와 openCamera()는 각각의 버튼을 클릭 시 앨범 혹은 카메라로 연결해 주는 사용자 정의 함수이다. (뒤에 구현 내용 정리)
생성한 버튼을 alert에 연결해 준 뒤 alert으로 화면을 전환한다.
권한 설정
카메라, 앨범 등 사용자 정보에 접근하기 위해서는 권한 요청이 필요하다.
info.plist에 들어가 위의 두 가지 권한을 추가해 준다.
- Privacy - Photo Library Usage Description : 사진앨범 권한
- Privacy - Camera Usage Description : 카메라 권한
델리게이트 설정
class ViewController: UIViewController {
...
let imgPicker = UIImagePickerController()
...
override func viewDidLoad() {
super.viewDidLoad()
imgPicker.delegate = self
}
...
extension ViewController : UIImagePickerControllerDelegate,
UINavigationControllerDelegate{
}
imgPicker라는 UIImagePickerController를 생성해 준다. 이는 카메라나 앨범에서 사진을 고를 수 있도록 하는 뷰컨트롤러이다.
imgPicker의 델리게이트를 뷰컨트롤러로 연결해 준다.
그리고 이미지피커를 사용하기 위해서는 두 가지 델리게이트를 연결해주어야 한다.
1. UIImagePickerDelegate
Image Picker와 상호작용하기 위해 반드시 구현해야 하는 메서드의 집합으로 이미지를 고르는 다양한 이벤트에 대한 동작을 지원받는다.
2. UINavigationControllerDelegate
갑자기 네비게이션 컨트롤러의 델리게이트를 왜 사용해야 하는지 의문이었다.
이는 화면 전환 동작에 대한 지원을 하는데 이미지 피커에서 사진을 선택할 때, 취소하고 원래 뷰 컨트롤러로 돌아올 때 등의 작업을 처리하기 위해 채택해야 한다고 한다.
openCamera, openLibrary() 구현
func openLibrary(){
imgPicker.sourceType = .photoLibrary
present(imgPicker, animated: false, completion: nil)
}
func openCamera(){
imgPicker.sourceType = .camera
present(imgPicker, animated: false, completion: nil)
}
이미지 피커의 sourceType을 각각 라이브러리와 카메라로 설정해준 뒤 이미지 피커로 화면을 전환해 준다.
여기까지 구현하게 되면 버튼 클릭 시 이미지 선택 창이 나와 이미지를 고를 수 있게 된다.
이미지 뷰에 가져온 이미지 설정하기
이제 선택한 이미지를 가져와 이미지 뷰에 설정해 보겠다.
이는 델리게이트에 정의되어 있는 didFinishPickingMediaWithInfo를 통해 설정할 수 있다.
이 메서드는 이름에서 알 수 있듯이 사용자가 사진을 다 고르게 되면 다양한 정보와 함께 호출된다.
extension ViewController:UIImagePickerControllerDelegate,UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
imgView.image = image
//print(info)
}
dismiss(animated: true, completion: nil)
}
}
우선 위와 같은 코드를 작성하기 전에 info를 출력해 보면
위와 같은 딕셔너리 형태의 정보가 제공된다.
UIImage를 얻기 위해서는 맨 마지막에 있는 UIImagePickerControllerOriginalImage를 사용하면 된다.
키 값은 UIImagePickerController.InfoKey.originalImage로 사용하면 된다.
따라서 옵셔널 바인딩을 통해 옵셔널 래핑을 풀어주고 이미지뷰의 이미지를 해당 이미지로 설정해 준다.
dismiss를 통해서 이미지 피커의 화면을 닫아준다.
(추가) 카메라 사용불가 예외 처리
시뮬레이터에서는 카메라를 사용할 수 없기 때문에 실제 아이폰이 아니라 시뮬레이터에서 이를 확인하면 카메라 선택 시 에러를 발생하게 된다.
따라서 이 부분에 대해서 예외처리를 추가적으로 해주었다.
enum CameraError : Error{
case notAvailable
}
우선 카메라 접근 불가라는 에러 유형을 하나 만들어주었다.
func openCamera() throws{
guard UIImagePickerController .isSourceTypeAvailable(.camera) else {
throw CameraError.notAvailable
}
imgPicker.sourceType = .camera
present(imgPicker, animated: false, completion: nil)
}
그리고 오류가 발생하는 openCamera함수를 위와 같이 고쳐 오류를 던져준다.
@IBAction func addBtnClick(_ sender:UIButton){
...
let camera = UIAlertAction(title: "카메라", style: .default) { (action) in
guard (try? self.openCamera()) != nil else{
let alert = UIAlertController(title: "카메라 접근 실패", message: "카메라를 이용할 수 없습니다.", preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: false, completion: nil)
print("Camera Not Available")
return
}
}
...
}
그리고 openCamera함수를 실행해 주는 부분에 가 위와 같이 고쳐준다.
만약에 오류가 발생한다면 카메라를 실행하지 못한다는 alert을 띄워준다.
'IOS App Programming > IOS 연습' 카테고리의 다른 글
Notifiaction Center VS Delegate Pattern (1) | 2024.02.13 |
---|---|
[IOS] UserDefaults란? (0) | 2023.04.12 |
[IOS] [AutoLayout] Safe Area와 Layout Margin (0) | 2023.03.15 |
[IOS] [AutoLayout] Stack View 정리 (1) | 2023.03.13 |
[IOS] [AutoLayout] intrinsic content size와 content hugging / compression resistance (1) | 2023.03.13 |
댓글