iOS SDK 選東西的 view controller & delegate 範例

iOS SDK 有很多選東西的 view controller,比方選照片,選顏色,選音樂等,使用它們十分簡單,只要利用 present 顯示,然後搭配 delegate 即可取得選取的內容。接下來就讓我們好好認識 iOS SDK 八種選東西的 view controller & 程式範例。

拍照或選相簿照片的 UIImagePickerController

拍照功能只能在實機測試。

  • 遵從 protocol UIImagePickerControllerDelegate & UINavigationControllerDelegate。
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

}
  • 連結 outlet & action,顯示 UIImagePickerController
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!

@IBAction func selectPhoto(_ sender: Any) {

let controller = UIImagePickerController()
controller.sourceType = .photoLibrary
//controller.sourceType = .camera
controller.delegate = self
present(controller, animated: true)
}

ps: 拍照功能須在 App 的 Info 頁面加入 Privacy — Camera Usage Description,設定權限請求的文字。

  • 從 imagePickerController(_:didFinishPickingMediaWithInfo:) 取得照片
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

let image = info[.originalImage] as? UIImage
imageView.image = image
dismiss(animated: true)
}
}

選顏色的 UIColorPickerViewController

  • 遵從 protocol UIColorPickerViewControllerDelegate。
extension ViewController: UIColorPickerViewControllerDelegate {

}
  • 顯示 UIColorPickerViewController
class ViewController: UIViewController {

@IBAction func selectColor(_ sender: Any) {

let controller = UIColorPickerViewController()
controller.delegate = self
present(controller, animated: true)
}
  • 取得選取的顏色,設為畫面的背景顏色。

iOS 15 以上的做法

extension ViewController: UIColorPickerViewControllerDelegate {
func colorPickerViewController(_ viewController: UIColorPickerViewController, didSelect color: UIColor, continuously: Bool) {
view.backgroundColor = color
}
}

舊版的做法

extension ViewController: UIColorPickerViewControllerDelegate {
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
view.backgroundColor = viewController.selectedColor
}
}

選擇 iOS Files App 裡檔案的 UIDocumentPickerViewController

  • 遵從 protocol UIDocumentPickerDelegate,記得要 import UniformTypeIdentifiers。
import UniformTypeIdentifiers

extension ViewController: UIDocumentPickerDelegate {

}
  • 連結 outlet & action,顯示 UIDocumentPickerViewController
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!

@IBAction func selectFile(_ sender: Any) {
let controller = UIDocumentPickerViewController(forOpeningContentTypes: [.png, .jpeg], asCopy: true)
controller.delegate = self
present(controller, animated: true)

}

生成 UIDocumentPickerViewController 時,參數 forOpeningContentTypes 控制檔案類型,在此我們傳入 [.png, .jpeg],因此只會顯示 png & jpg 的圖檔。參數 asCopy 傳入 true 將讓我們能在 App 裡存取檔案。

  • 取得選取的檔案路徑,從路徑產生圖片後,設定 outlet imageView 的圖片。
extension ViewController: UIDocumentPickerDelegate {

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {

if let url = urls.first,
let image = UIImage(contentsOfFile: url.path){
imageView.image = image
}
}
}

選擇 iOS Music App 音樂的 MPMediaPickerController

只能在實機測試。若有訂閱 Apple Music,可讀取 Apple Music 的音樂,否則只能讀取自己存在 Music App 的音樂。

  • 遵從 protocol MPMediaPickerControllerDelegate,記得要 import MediaPlayer。
import MediaPlayer

extension ViewController: MPMediaPickerControllerDelegate {

}
  • 顯示 MPMediaPickerController
import MediaPlayer

class ViewController: UIViewController {

@IBAction func selectMusic(_ sender: Any) {

let controller = MPMediaPickerController(mediaTypes: .music)
controller.delegate = self
present(controller, animated: true)
}

ps: 須在 App 的 Info 頁面加入 Privacy — Media Library Usage Description,設定權限請求的文字。

  • 取得選取的音樂並播放。
extension ViewController: MPMediaPickerControllerDelegate  {
func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
let musicPlayer = MPMusicPlayerController.systemMusicPlayer
musicPlayer.setQueue(with: mediaItemCollection)
musicPlayer.play()
mediaPicker.dismiss(animated: true)
}
}

選字型的 UIFontPickerViewController

  • 遵從 protocol UIFontPickerViewControllerDelegate。
extension ViewController: UIFontPickerViewControllerDelegate {

}
  • 連結 outlet & action,顯示 UIFontPickerViewController。
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!

@IBAction func selectFont(_ sender: Any) {
let fontConfig = UIFontPickerViewController.Configuration()
fontConfig.includeFaces = true
let fontPicker = UIFontPickerViewController(configuration: fontConfig)
fontPicker.delegate = self
present(fontPicker, animated: true)
}
  • 取得選取的字型,設為 outlet label 的字型。
extension ViewController: UIFontPickerViewControllerDelegate {

func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
if let selectedFontDescriptor = viewController.selectedFontDescriptor {
label.font = UIFont(descriptor: selectedFontDescriptor, size: label.font.pointSize)
}
dismiss(animated: true)

}
}

選擇通訊錄聯絡人的 CNContactPickerViewController

  • 遵從 protocol CNContactPickerDelegate,記得要 import ContactsUI。
import ContactsUI

extension ViewController: CNContactPickerDelegate {
}
  • 顯示 CNContactPickerViewController
import ContactsUI

class ViewController: UIViewController {

@IBAction func selectContact(_ sender: Any) {
let controller = CNContactPickerViewController()
controller.delegate = self
present(controller, animated: true)
}
  • 取得聯絡人的名字跟電話。
extension ViewController: CNContactPickerDelegate {

func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
print(contact.givenName)
if let phoneNumber = contact.phoneNumbers.first?.value {
print(phoneNumber.stringValue)
}
}
}

編輯影片的 UIVideoEditorController

只能在實機測試。

  • 遵從 protocol UIVideoEditorControllerDelegate & UINavigationControllerDelegate。
extension ViewController: UINavigationControllerDelegate, UIVideoEditorControllerDelegate { 

}
  • 顯示 UIVideoEditorController
class ViewController: UIViewController {

@IBAction func editVideo(_ sender: Any) {

if let path = Bundle.main.path(forResource: "Cat", ofType: "mp4"),
UIVideoEditorController.canEditVideo(atPath: path){
let controller = UIVideoEditorController()
controller.videoPath = path
controller.delegate = self
present(controller, animated: true)
}

}

假設影片檔案如下:

  • 取得編輯後的影片,將它顯示到畫面上並播放。為了使用 AVPlayerLayer,記得要 import AVFoundation。
extension ViewController:  UINavigationControllerDelegate, UIVideoEditorControllerDelegate {

func videoEditorController(_ editor: UIVideoEditorController, didSaveEditedVideoToPath editedVideoPath: String) {
let player = AVPlayer(url: URL(fileURLWithPath: editedVideoPath))
let playerLayer = AVPlayerLayer()
playerLayer.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
playerLayer.videoGravity = .resizeAspectFill
playerLayer.player = player
view.layer.addSublayer(playerLayer)
player.play()
dismiss(animated: true)
}
}

多選照片的 PHPickerViewController

作品集

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com