#25 protocol & delegate 練習 | 照片編輯App

模仿 iOS 的照片 App 編輯照片

✏️畫面呈現

畫面呈現

✏️App功能

  1. UIImagePickerController 選照片
  2. 調整圖片比例
  3. 鏡像翻轉、旋轉
  4. 增加背景顏色 UIColorPickerViewController
  5. 儲存相片/ UIActivityViewController分享照片

程式說明

選完照片後,將 ViewController 設為 UIImagePickerController 的 delegate 並呼叫imagePickerController(_:didFinishPickingMediaWithInfo:)

必須遵從protocol
➡️ UIImagePickerControllerDelegate & UINavigationControllerDelegate 才有資格當 UIImagePickerController 的 delegate

合併使用UIAlertController,preferredStyle: .actionSheet,使視窗由下往上呈現
選項有拍照或相片集,並使用closure呼叫.sourceType,顯示結果

@IBAction func addPhoto(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self

let alertController = UIAlertController(title: "Select Photo", message:nil, preferredStyle: .actionSheet)

let cancelController = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelController)

if UIImagePickerController.isSourceTypeAvailable(.camera) {
let cameraAction = UIAlertAction(title: "Take Photo", style: .default) { _ in imagePicker.sourceType = .camera
self.present(imagePicker, animated: true, completion: nil)
}
alertController.addAction(cameraAction)
}
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
let photoLibraryAction = UIAlertAction(title: "Photo Library", style: .default) { _ in imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
alertController.addAction(photoLibraryAction)
}
present(alertController, animated: true, completion: nil)


}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// didFinishPickingMediaWithInfo,選完照片後,將使用者選的照片顯示到 image view 上(將照片轉型成UIImage)
let image = info[.originalImage] as? UIImage
imageView.image = image

// 離開視窗
dismiss(animated: true, completion: nil)

}

參數 info 是 dictionary,包含不同型別的內容, 型別為 Any,讀取後要再轉型才能使用

將選好的照片傳到下一頁進行編輯,使用右上角的 [ edit 按鈕 ] 將選完的照片傳入下一頁

@IBSegueAction func photoEdit(_ coder: NSCoder) -> EditingViewController? {
let controller = EditingViewController(coder: coder)
controller?.image = imageView
return controller
}

改變背景顏色時,呼叫UIColorPickerViewController,並找delegate幫忙

@IBAction func colorChange(_ sender: Any) {
let controller = UIColorPickerViewController()
controller.delegate = self
present(controller, animated: true)
}

func colorPickerViewController(_ viewController: UIColorPickerViewController, didSelect color: UIColor, continuously: Bool) {
imageBackgroundView.backgroundColor = color
dismiss(animated: true, completion: nil)
}

最後一步,儲存照片!

@IBAction func savePhoto(_ sender: Any) {
// 利用 UIGraphicsImageRenderer 將 view 變成 UIImage
let renderer = UIGraphicsImageRenderer(size: imageBackgroundView.bounds.size)
// function image(actions:) 產生圖片, drawHierarchy(in:afterScreenUpdates:)繪製成圖片,讓 imageBackgroundView 和它的 subview 出現在圖片裡
let image = renderer.image(actions: { context in imageBackgroundView.drawHierarchy(in: imageBackgroundView.bounds, afterScreenUpdates: true) })
// UIActivityViewController 分享圖片
let activityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
present(activityViewController, animated: true, completion: nil)

}

🔆 GitHub

📝 參考來源

--

--