iOS 系统提供的媒体资源选择器(UIImagePickerController)

简介

图片或者视频的选择功能几乎是每个APP必不可少的,UIImagePickerController 是 iOS 系统提供的一个方便的媒体选择器,允许用户从照片库中选择图片或视频,或者使用相机拍摄新照片和视频。

它的页面简单易用,代码稳定可靠,适合用于单张图片或者视频的选择场景。

配置 UIImagePickerController

1.实现图片选择

UIImagePickerController的配置很简单,只有几个属性需要我们来设置,设置好属性和代理之后,只需要向其它页面一样将其present出来即可,简单的配置如下:

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.mediaTypes = ["public.image"]
        present(imagePickerController, animated: true, completion: nil)
    }
    
    // Delegate methods
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let selectedImage = info[.originalImage] as? UIImage {
            // 使用选中的图片
        }
        dismiss(animated: true, completion: nil)
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }

在上面的代码中,

1.设置了UIImagePickerController的sourceType类型为photoLibrary意味着着我们将从媒体库中选择资源。

2.而mediaTypes属性设置为"public.image"以为着我们只读取图片资源。

3.接着配置了UIImagePickerController的代理并且让视图控制器遵循代理并实现

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: UIImagePickerController.InfoKey : Any)

func imagePickerControllerDidCancel(_ picker: UIImagePickerController)

两个代理方法,在我们选择图片后可以从info中直接读取出我们选择的图片资源。

效果如下:

2.实现视频选择

想要选择视频媒体资源,我们只需要修改它的mediaTypes属性为"public.movie",代码如下:

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.mediaTypes = ["public.movie"]
        present(imagePickerController, animated: true, completion: nil)
    }
Swift 复制代码
    // Delegate methods
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let mediaType = info[.mediaType] as? String {
            if mediaType == "public.image" {
                // 使用选中的图片
                if let selectedImage = info[.originalImage] as? UIImage {
                    // 使用选中的图片
                }
            } else if mediaType == "public.movie" {
                // 使用选中的视频
                if let videoURL = info[.mediaURL] as? URL {
                    // 使用选中的视频
                }
            }
        }
        dismiss(animated: true, completion: nil)
    }

效果如下:

这样列表中就只有视频资源了,当然如果想要两个类型都可以选择的话,那么就两个字符串都添加进去"public.movie","public.image",毕竟这是一个String类型。

3.直接拍摄图片

如果想要修改媒体资源的来源,这时候则需要调整sourceType属性,设置为.camera。mediaTypes属性仍然为"public.image",代码如下:

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .camera
        imagePickerController.mediaTypes = ["public.image"]
        present(imagePickerController, animated: true, completion: nil)
    }

效果如下:

会有一个系统为我们提供的拍照页面,并附带一个取消按钮。拍照完成后,它的图片也会通过代理方法传递到当前控制器。

4.直接拍摄视频

参考上面的例子,直接拍摄的视频我们需要保持sourceType属性仍然为.camera,而mediaTypes属性设置为"public.movie",(如果两个都可以的话仍然是设置mediaTypes属性为"public.movie","public.image")。

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .camera
        imagePickerController.mediaTypes = ["public.move"]
        present(imagePickerController, animated: true, completion: nil)
    }

效果如下:

5.编辑媒体资源

UIImagePickerController还有一个allowsEditing属性,默认为false,当设置为true时,意味着在我们选择一个媒体资源后,会进入一个资源的编辑页面,编辑完成之后才会进入代理方法,这时候我们除了通过originalImage获取图片之外还可以通过editedImage来获取编辑后的图片。

而视频资源都是通过mediaURL来获取。

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.allowsEditing = true
        imagePickerController.mediaTypes = ["public.movie", "public.image"]
        present(imagePickerController, animated: true, completion: nil)
    }

6.限制最大视频时长

我们可以通过videoMaximumDuration属性来设置视频资源的最大时长,在上传视频资源时,通常都会有一个长度限制,videoMaximumDuration的默认值为10,意味着大于10秒的视频不会显示在我们的列表。

7.自定义相机样式

UIImagePickerController也为我们保留了一些可以自定义相机样式的空间。

通过设置showsCameraControls属性为false。隐藏系统为我们提供的相机页面样式。

Swift 复制代码
    @objc func showImagePickerView() {
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .camera
        imagePickerController.allowsEditing = true
        imagePickerController.mediaTypes = ["public.movie", "public.image"]
        imagePickerController.showsCameraControls = false
        present(imagePickerController, animated: true, completion: nil)
    }

效果如下:

看起来有一点奇怪,不过当我们把它的控制视图隐藏之后确实就是这样,之后我们就需要多个属性配合来自己来实现它的拍照和录像的UI,而拍照和录像的方法UIImagePickerController已经提供给我们了:

Swift 复制代码
// 拍照
open func takePicture()
// 录像
open func startVideoCapture() -> Bool
// 停止录像
open func stopVideoCapture()
// 设置相机模式
open var cameraCaptureMode: UIImagePickerController.CameraCaptureMode

还可以通过cameraViewTransform属性来修改预览画面的位置,

通过cameraOverlayView属性来自定义我们的控制视图。

下面我们就来实现一个简单自定义拍照的UI,代码如下:

Swift 复制代码
    @objc func showImagePickerView() {
        
        let view = UIView(frame: CGRect(x: 0, y: self.view.bounds.size.height - 200, width: self.view.bounds.size.width, height: 200.0))
        let button = UIButton()
        button.setImage(UIImage(named: "dynamic_post_photo_camare"), for: .normal)
        button.layer.masksToBounds = true
        button.layer.cornerRadius = 30.0
        view.addSubview(button)
        button.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.width.height.equalTo(60.0)
            make.top.equalToSuperview().offset(40.0)
        }
        button.addTarget(self, action: #selector(takePhoto), for: .touchUpInside)
        
        guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.sourceType = .camera
        imagePickerController.allowsEditing = true
        imagePickerController.mediaTypes = ["public.movie", "public.image"]
        imagePickerController.showsCameraControls = false
        imagePickerController.cameraViewTransform = CGAffineTransform(translationX: 0, y: 100.0)
        imagePickerController.cameraOverlayView = view
        present(imagePickerController, animated: true, completion: nil)
        self.imagePickerController = imagePickerController
    }
    
    @objc func takePhoto() {
        self.imagePickerController?.takePicture()
    }

效果如下:

结语

通过这篇博客,我们深入探讨了 UIImagePickerController 的各种功能和实现方法。我们了解了如何选择和拍摄图片及视频,如何编辑媒体,如何限制视频的最大长度,以及如何自定义相机样式。这些功能为开发者提供了丰富的工具,帮助我们创建出更加直观和用户友好的应用。

UIImagePickerController 是一个强大而灵活的组件,能够满足大多数基础的媒体选择和拍摄需求。尽管如此,对于更复杂的场景,苹果也提供了 PHPickerViewController 和其他更高级的框架,供开发者进一步探索和使用。下一篇博客我们来探讨它。

希望通过这篇博客,你能够更加熟练地使用 UIImagePickerController,并在你的项目中实现更加丰富的媒体处理功能。如果你有任何疑问或需要进一步的帮助,欢迎在评论区留言,我们共同探讨进步!

相关推荐
ZC跨境爬虫3 天前
跟着 MDN 学CSS day_30:(玩转列表样式,从基础到进阶)
前端·css·html·tensorflow·媒体
2601_957888563 天前
数字化转型下,企业新媒体矩阵系统的底层架构与选型实践
矩阵·架构·媒体
李永奉4 天前
杰理SDK开发-实现首次连接默认媒体音量
媒体
ZC跨境爬虫4 天前
跟着 MDN 学CSS day_25:(高级区块效果)
前端·css·html·tensorflow·媒体
EasyDSS4 天前
企业融媒体平台/私有化视频会议解决方案EasyDSS重构企业视频高效运维体系
重构·音视频·媒体
AI服务老曹5 天前
源码交付与低代码解耦:基于 Docker 的边缘计算 AI 视频管理平台二次开发深度实战(兼容 GB28181/RTSP)
人工智能·docker·媒体
Hommy885 天前
【剪映小助手】媒体处理接口
媒体·视频剪辑自动化·剪映api·开源剪映小助手·剪辑skills
lishi_19915 天前
一键部署MoviePilotV2实现NAS全自动追剧
python·媒体·moviepilot
dayuOK63076 天前
用了AI之后,我的个人风格反而更明显了
人工智能·职场和发展·自动化·新媒体运营·媒体
EasyDSS6 天前
从散装到一体化:EasyDSS平台3步打造私有化企业融媒体平台
媒体