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,这是规定的…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
