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

news2024/12/24 2:22:36

简介

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

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

配置 UIImagePickerController

1.实现图片选择

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

    @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"],代码如下:

    @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)
    }
    // 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"],代码如下:

    @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"])。

    @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来获取。

    @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。隐藏系统为我们提供的相机页面样式。

    @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已经提供给我们了:

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

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

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

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

    @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,并在你的项目中实现更加丰富的媒体处理功能。如果你有任何疑问或需要进一步的帮助,欢迎在评论区留言,我们共同探讨进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于STC8H系列单片机的比较器功能调试

基于STC8H系列单片机的比较器功能调试 STC8H4K64TL单片机介绍STC8H4K64TL单片机管脚图(48个引脚)STC8H4K64TL单片机串口仿真与串口通信STC8H4K64TL单片机管脚图(32个引脚)STC8H4K64TL单片机管脚图(20个引脚)STC8H系列单片机管脚说明STC8H系列单片机I/O口STC8H系列单片机I…

八股文真的有作用吗?

八股文在实际工作中的作用:助力、阻力还是空谈? 无论如何讨论,八股文都是面试中不可或缺的一环。一般来说,准入门槛是由“招聘”这个“游戏”的设计者设计的,旨在快速高效地筛选出合适的人选。 但是我还是要说&#x…

buu做题(12)

[CISCN 2019 初赛]Love Math <?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c20-1$content $_GET[c];if (strlen($content) > 80) {die("太长了不会算");…

【重磅推出】★全部CFA FRM CAIA ESG原創資料整理[2024版+2025版更新中]

【重磅推出】★全部CFA FRM原創資料整理[2024版2025版更新中] 申明&#xff1a;大部分資料都是本人整理原創內容&#xff0c;最新資料有參考CFA FRM協會&#xff08;有征求協會同意&#xff0c;是可以分享到網上給大家使用的&#xff09;&#xff0c; 去年收集整理了一個帖子&…

抖音小店新宠儿成都夏光汝网络科技

在当今这个数字化时代&#xff0c;电商平台的兴起为无数商家和个人创业者提供了前所未有的机遇&#xff0c;而抖音小店作为抖音平台上的重要电商板块&#xff0c;更是以其庞大的用户基数和高度活跃的社交属性&#xff0c;成为了众多品牌与商家争相入驻的热门选择。其中&#xf…

理学、工学、农学、医学、哲学、经济学、法学、教育学、文学、军事学、管理学、艺术学、历史学等学科的核心思想和基本理论

以下是以表格形式列出的理学、工学、农学、医学、哲学、经济学、法学、教育学、文学、军事学、管理学、艺术学、历史学等学科的核心思想和基本理论&#xff1a; 晓北斗推荐-多学科知识体系 学科核心思想基本理论理学探索自然、社会和人类思维的本质和规律物理学、化学、生物学、…

Flink 实时数仓(四)【DWD 层搭建(二)流量域事实表】

前言 昨天刚搬到新校区&#xff0c;新校区小的可怜&#xff0c;好在之后出去实习交通可以方便点&#xff1b;待在学院太受限了&#xff0c;早点离开&#xff01; 今天开始完成 DWD 层剩余的需求&#xff0c;上一节我们把日志数据根据不同类型分流写入到了不同的主题&#xff1b…

LangChain +Streamlit+ Llama :将对话式人工智能引入您的本地设备成为可能(上篇)

&#x1f99c;️ LangChain Streamlit&#x1f525; Llama &#x1f999;&#xff1a;将对话式人工智能引入您的本地设备&#x1f92f; 将开源LLMs和LangChain集成以进行免费生成式问答&#xff08;不需要API密钥&#xff09; 在过去的几个月中&#xff0c;大型语言模型(LLMs)得…

云计算学习——5G网络技术

系列文章目录 提示&#xff1a;仅用于个人学习&#xff0c;进行查漏补缺使用。 Day1 网络参考模型 Day2 网络综合布线与应用 Day3 IP地址 Day4 华为eNSP网络设备模拟器的基础安装及简单使用 Day5 交换机的基本原理与配置 Day6 路由器的原理与配置 Day7 网络层协议介绍一 Day8 …

【Pyhton】数据类型之详讲字符串(上)

本篇文章将详细讲解字符串&#xff1a; 1、定义 定义字符串时&#xff0c;字符串的内容被双引号&#xff0c;单引号&#xff0c;三单引号&#xff0c;三双引号中的其中一个被括住。 例如&#xff1a; 双引号&#xff1a; v1"haha" 单引号&#xff1a; v1hahah…

数据结构-1.初始包装类与泛型

本节目标:学习包装类与泛型为阅读java集合源码打下基础. 1.包装类 在 Java 中&#xff0c;由于基本类型不是继承自 Object &#xff0c;为了在泛型代码中可以支持基本类型&#xff0c; Java 给每个基本类型都对应了一个包装类型. 1.1基本数据类型对应包装类 基本数据类型包装类…

编码的理解

人类的文字信息由各种各样的符号构成 文字-----符号 这些符号是不能在磁盘或内存当中存储的&#xff0c;计算机最早是由老美发明出来的&#xff0c;内存和磁盘当中只有 0&#xff0c;1&#xff0c;严格来说内存和磁盘中只能表示整型&#xff0c;那么我们应该怎么表示符号----…

linux进程控制——进程替换——exec函数接口

前言&#xff1a; 本节内容进入linux进程控制板块的最后一个知识点——进程替换。 通过本板块的学习&#xff0c; 我们了解了进程的基本控制方法——进程创建&#xff0c; 进程退出&#xff0c; 进程终止&#xff0c; 进程替换。 进程控制章节和上一节进程概念板块都是在谈进程…

智算新风向丨趋动科技获中国信通院泰尔实验室首张智算资源池化能力泰尔测评证书

近日&#xff0c;趋动科技“OrionX AI算力资源池化软件”经中国泰尔实验室依据《FG-Z14-0172-01智算资源池化平台测试方案》评估测试&#xff0c;获得智算资源池化能力泰尔测评证书&#xff0c;成为该领域首个完成此评价的产品。 图1.OrionX通过智算资源池化平台评测 随着AI大…

智能巡检企业级域名 SSL 证书

一、概述 SSL 证书是一种数字证书&#xff0c;用于在用户和服务器之间建立加密链接&#xff0c;确保数据传输的安全性&#xff0c;防止数据在传输过程中被截获或篡改。SSL 证书不仅保护了数据传输过程中的隐私和完整性&#xff0c;还可以帮助验证网站的身份&#xff0c;防止钓…

基于SpringBoot+Vue的科研管理系统(带1w+文档)

基于SpringBootVue的科研管理系统(带1w文档) 基于SpringBootVue的科研管理系统(带1w文档) 科研的管理系统设计过程中采用Java开发语言,B/S结构&#xff0c;采取springboot框架&#xff0c;并以MySql为数据库进行开发。结合以上技术&#xff0c;对本系统的整体、数据库、功能模块…

鸿蒙系统开发【加解密算法库框架】安全

加解密算法库框架 介绍 本示例使用ohos.security.cryptoFramework相关接口实现了对文本文件的加解密、签名验签操作。 实现场景如下&#xff1a; 1&#xff09;软件需要加密存储本地文本文件&#xff0c;需要调用加解密算法库框架选择密钥文本文件&#xff0c;对本地文本文…

PostgreSQL11 | 触发器

本文章代码已在pgsql11.22版本上运行且通过&#xff0c;展示页由pgAdmin8.4版本提供 上一篇总结了原著的第十章有关pgsql的视图的用法&#xff0c;本篇将总结pgsql的触发器的用法。 触发器 使用触发器可以自动化完成一些在插入数据或修改数据时&#xff0c;某些需要同期同步的…

【vulnhub】Depth靶机

靶机安装 下载地址&#xff1a;https://download.vulnhub.com/depth/DepthB2R.ova 运行环境&#xff1a;VMware运行该虚拟机 信息收集 靶机IP发现 nmap 192.168.93.0/24 端口扫描 nmap -A 192.168.93.154 -p- 只开起了8080端口 进行目录扫描8080端口 dirsearch -u http…

学习记录(9):Prompt提示词技巧

依旧照例先感谢前辈们的慷慨分享 今天学习的是这篇文章↓ 原文&#xff1a;转自公主号“博金斯的AI笔记” —《4篇Prompt论文的提示词技巧, 3 个 GPTs 实例测试》 文章目录 一、提示词框架二、逻辑链&#xff08;Chain of thought&#xff09;三、思维树&#xff08;Tree of th…