SwiftUI调用相机拍照
在 SwiftUI 中实现拍照功能,需要结合 UIViewControllerRepresentable 和 UIImagePickerController 来实现相机功能。下面是一个详细的示例,展示如何使用 SwiftUI 来实现拍照功能:
1. 创建一个 ImagePicker 组件
首先,创建一个 UIViewControllerRepresentable 结构,用于包装 UIImagePickerController。
import SwiftUI
import UIKitstruct ImagePicker: UIViewControllerRepresentable {@Binding var selectedImage: UIImage?@Environment(\.presentationMode) var presentationModevar sourceType: UIImagePickerController.SourceType = .cameraclass Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {let parent: ImagePickerinit(parent: ImagePicker) {self.parent = parent}func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {if let image = info[.originalImage] as? UIImage {parent.selectedImage = image}parent.presentationMode.wrappedValue.dismiss()}func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {parent.presentationMode.wrappedValue.dismiss()}}func makeCoordinator() -> Coordinator {Coordinator(parent: self)}func makeUIViewController(context: Context) -> UIImagePickerController {let picker = UIImagePickerController()picker.delegate = context.coordinatorpicker.sourceType = sourceTypereturn picker}func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}
2. 使用 ImagePicker 组件
接下来,在你的主视图中使用 ImagePicker 组件来实现拍照功能。
import SwiftUIstruct ContentView: View {@State private var isImagePickerPresented = false@State private var selectedImage: UIImage?var body: some View {VStack {if let selectedImage = selectedImage {Image(uiImage: selectedImage).resizable().scaledToFit().frame(width: 300, height: 300)} else {Text("No Image Selected").frame(width: 300, height: 300).background(Color.gray)}Button(action: {isImagePickerPresented = true}) {Text("Take Photo").padding().background(Color.blue).foregroundColor(.white).cornerRadius(10)}.padding()}.sheet(isPresented: $isImagePickerPresented) {ImagePicker(selectedImage: $selectedImage)}}
}struct ContentView_Previews: PreviewProvider {static var previews: some View {ContentView()}
}
解释
-
ImagePicker组件:UIViewControllerRepresentable协议用来将UIImagePickerController引入 SwiftUI。makeUIViewController和updateUIViewController方法创建和更新UIImagePickerController。Coordinator类作为UIImagePickerController的代理,处理图片选择和取消操作。
-
ContentView:- 使用
@State属性包装变量isImagePickerPresented来控制ImagePicker的显示。 - 使用
@State属性包装变量selectedImage来存储选取的图片。 - 当点击 “Take Photo” 按钮时,显示
ImagePicker。 sheet修饰符用于在isImagePickerPresented为true时呈现ImagePicker。
- 使用
通过这种方式,你可以在 SwiftUI 应用中实现拍照功能。请注意,拍照功能只能在真实设备上使用,因为模拟器不支持摄像头。
在 iOS 应用中访问相机需要在 Info.plist 文件中添加 NSCameraUsageDescription 键,以告知用户为什么需要访问相机。否则,应用在尝试访问相机时会崩溃。
添加 NSCameraUsageDescription 到 Info.plist
-
打开你的 Xcode 项目。
-
在项目导航中,找到并点击你的
Info.plist文件。 -
在
Info.plist中,添加一个新的键值对:- 键:
NSCameraUsageDescription - 值:解释你的应用需要使用相机的原因,比如 “This app requires access to the camera to take photos.”
- 键:
示例:
<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera to take photos.</string>
如果你使用 Xcode 的图形化界面,可以按以下步骤操作:
- 打开
Info.plist文件。 - 点击右键选择 “Add Row”。
- 在新行的键列中输入
NSCameraUsageDescription。 - 在值列中输入对用户的说明,比如 “This app requires access to the camera to take photos.”
更新后的示例代码
完成上述步骤后,你可以重新运行之前的代码:
import SwiftUI
import UIKitstruct ImagePicker: UIViewControllerRepresentable {@Binding var selectedImage: UIImage?@Environment(\.presentationMode) var presentationModevar sourceType: UIImagePickerController.SourceType = .cameraclass Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {let parent: ImagePickerinit(parent: ImagePicker) {self.parent = parent}func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {if let image = info[.originalImage] as? UIImage {parent.selectedImage = image}parent.presentationMode.wrappedValue.dismiss()}func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {parent.presentationMode.wrappedValue.dismiss()}}func makeCoordinator() -> Coordinator {Coordinator(parent: self)}func makeUIViewController(context: Context) -> UIImagePickerController {let picker = UIImagePickerController()picker.delegate = context.coordinatorpicker.sourceType = sourceTypereturn picker}func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}struct ContentView: View {@State private var isImagePickerPresented = false@State private var selectedImage: UIImage?var body: some View {VStack {if let selectedImage = selectedImage {Image(uiImage: selectedImage).resizable().scaledToFit().frame(width: 300, height: 300)} else {Text("No Image Selected").frame(width: 300, height: 300).background(Color.gray)}Button(action: {isImagePickerPresented = true}) {Text("Take Photo").padding().background(Color.blue).foregroundColor(.white).cornerRadius(10)}.padding()}.sheet(isPresented: $isImagePickerPresented) {ImagePicker(selectedImage: $selectedImage)}}
}struct ContentView_Previews: PreviewProvider {static var previews: some View {ContentView()}
}
通过添加 NSCameraUsageDescription,应用在请求访问相机时会向用户显示一条提示,解释为什么需要访问相机,从而避免因未声明权限而导致的崩溃。
相关文章:
SwiftUI调用相机拍照
在 SwiftUI 中实现拍照功能,需要结合 UIViewControllerRepresentable 和 UIImagePickerController 来实现相机功能。下面是一个详细的示例,展示如何使用 SwiftUI 来实现拍照功能: 1. 创建一个 ImagePicker 组件 首先,创建一个 U…...
elasticsearch (dsl)
正排索引 和 倒排索引 正排索引:通过id ,查询content 倒排索引:通过content,查询到符合的 ids eg: 正排索引就是通过《静夜思》,找到整片文章。 倒排索引通过“明月”,找到《静夜思》 《望…...
聊聊大模型微调训练全流程的思考
前言 参考现有的中文医疗模型:MedicalGPT、CareGPT等领域模型的训练流程,结合ChatGPT的训练流程,总结如下: 在预训练阶段,模型会从大量无标注文本数据集中学习领域/通用知识;其次使用{有监督微调}(SFT)优化…...
Python变量符号:深入探索与实用指南
Python变量符号:深入探索与实用指南 在Python编程的世界中,变量符号扮演着至关重要的角色。它们不仅是存储数据的容器,更是构建复杂逻辑和算法的基础。然而,对于初学者来说,Python的变量符号可能会带来一些困惑和挑战…...
实验八 页面置换模拟程序设计
网上找到的程序得到的答案经过手算验证是错的,所以自己实现了一个,具体实现看代码吧,多余的操作已经去掉了。 #include <stdio.h> #include <stdlib.h> #include <stdbool.h>#define VM_PAGE 7 /*假设每个页面可以存放10…...
Spring类加载机制揭秘:深度解析“卸载”阶段
1. 引言 在Spring框架中,类的加载和卸载是一个复杂但至关重要的过程。加载主要涉及将类的字节码加载到JVM中,创建对应的Class对象,并准备使其可用的过程。而卸载,则是指当一个类不再被需要时,将其从JVM中清除…...
Jupyter Notebook快速搭建
Jupyter Notebook why Jupyter Notebook Jupyter Notebook 是一个开源的 Web 应用程序,允许你创建和分享包含实时代码、方程、可视化和解释性文本的文档。其应用包括:数据清洗和转换、数值模拟、统计建模、数据可视化、机器学习等等。 Jupyter Notebo…...
Linux C语言:数组的定义和初始化
一、数组 1、定义 在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来,具有一定顺序关系的若干个变量的集合就是数组 。 2、特点 组成数组的各个变量称为数组的元素数组中各元素的数据类型要求相同元素在内存中是连…...
spring框架限制接口是否要登录过才能访问
1、引入spring 、spring boot依赖,这部分不再多说,正常开发spring boot项目就可以。 2、定义类,实现WebMvcConfigurer接口 package com.hmblogs.config;import com.hmblogs.config.web.interceptor.PortalTokenInterceptor; import org.spri…...
【全开源】废品回收垃圾回收小程序APP公众号源码PHP版本
🌟废品回收小程序:绿色生活的新助手🌱 一、引言 随着环保意识的逐渐提高,废品回收成为了我们日常生活中的重要一环。但是,如何更方便、高效地进行废品回收呢?今天,我要向大家推荐一款超级实用…...
勒索软件分析_目标文件扫描行为分析
BlackBasta首先通过 FindFirstVolumeW 与 FindNextVolumeW 实现系统中第一个卷的搜索和其余卷的遍历,之后通过 GetVolumePathNamesForVolumeNameW 检索指定卷的驱动器号和挂载的文件夹路径列表,然后通过 GetVolumeInformationW 获取关于指定卷的信息,具体代码如下所示。 Fin…...
2024050401-重学 Java 设计模式《实战代理模式》
重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」 一、前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不到前进…...
HTML跨年烟花
目录 写在前面 关于小编 HTML简介 程序设计 系列文章 写在后面 写在前面 学会了这个html烟花秀,跨年就不缺文案喽~ 关于小编 平易近人,慈眉善目,爱交朋友,舍己为人,和蔼可亲,能说会道,…...
微服务第二轮
学习文档 背景 由于每个微服务都有不同的地址或端口,入口不同 请求不同数据时要访问不同的入口,需要维护多个入口地址,麻烦 前端无法调用nacos,无法实时更新服务列表 单体架构时我们只需要完成一次用户登录、身份校验ÿ…...
线性模型-分类
一、线性判别分析LDA 线性判别分析是一种经典的线性学习方法,在二分类问题上最早是Fisher提出的,亦称为Fisher判别分析。 Fisher判别分析是一种用于降维和分类的统计方法,旨在找到可以最好区分不同类别的特征。它基于类内方差和类间方差的比…...
OpenAI前董事会成员称Sam Altman因 “ 向董事会撒谎 ” 而被解雇
据前 OpenAI 董事会成员称,据称 Altman 隐瞒了他对 OpenAI 创业基金的所有权。 更详细的内容请参考原文: https://cointelegraph.com/news/sam-altman-fired-openai-board-allegations 据一位前董事会成员称,Sam Altman 因涉嫌向董事会隐瞒…...
【启明智显分享】WIFI6开发板ZX6010:开源OpenWrt SDK,接受定制!
在数字化飞速发展的当下,网络速度和稳定性已成为各行各业不可或缺的关键因素。今天,我们为大家推荐一款基于IPQ6010的AX1800方案ZX6010 Wi-Fi6开发板,为您的网络世界注入强大动力。 一、超强硬件配置 ZX6010搭载IPQ6010四核ARM Cortex A53处…...
C语言能否使⽤ fflush( ) 函数清除多余的输⼊?
一、问题 在从终端输⼊数据时,很可能会输⼊多余的数据,那么能否使⽤ fflush( ) 函数清除呢? 二、解答 fflush( ) 函数只是⽤在⽂件以写的⽅式打开时,将缓冲区内容写⼊到⽂件。因此 fflush( ) 函数仅对输出流有效,对输…...
如何把试卷上的字去掉再打印?分享三种方法
如何把试卷上的字去掉再打印?随着科技的不断发展,现代教育和学习方式也在逐渐变革。在学习过程中,我们经常需要对试卷进行整理和分析,以便更好地掌握知识点和复习。然而,传统的试卷整理方法往往效率低下且容易出错。幸…...
Android开机动画压缩包zip,自制开机动画(基于Android10.0.0-r41)
文章目录 Android开机动画压缩包zip,自制开机动画1.Android加载压缩包原理2.自制开机动画 Android开机动画压缩包zip,自制开机动画 1.Android加载压缩包原理 这里有个md文件我们看下 核心部分, 首先要创建一个文件叫做desc.txt,这是规定的…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
