IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS14+Swift5.x+Xcode12学习笔记(6)——拍照与音乐 -> 正文阅读

[移动开发]iOS14+Swift5.x+Xcode12学习笔记(6)——拍照与音乐

前言

如果想让你的App具有拍照与摄像的功能,如果你的App不是专门的拍照软件如美颜相机软件等,那么你不需要做很多操作,iOS内置的SDK已经帮我们准备好了界面和服务,我们只需要直接调用就可以了。
一个需要处理传照片的App,照片的来源共有三个。

  • 相机
  • 照片图库(Photo Library)
  • 相簿(Photos Album)

相机一般用于即时拍摄并选择这张照片;照片图库会先呈现照片目录给使用者进行选择, 再从选择的目录中选择你需要的照片;相簿直接从Camera Roll这个相簿中选择照片,里面存放设备内所有的照片。

检查设备是否具有拍照功能

不同的iOS设备的相机或闪光灯的位置可能不同,例如可能只有后镜头而没有前镜头,或者根本没有拍照功能。UIImagePickerController为我们提供了检查的方法。

override func viewDidLoad() {
	super.viewDidLoad()

	if UIImagePickerController.isSourceTypeAvaliable(.camera) {
		print("本设备具有拍照功能")

		if UIImagePickerViewController.isCameraDeviceAvaliable(.front) {
			print("有前方镜头")
		}
		
		if UIImagePickerViewController.isCameraDeviceAvaliable(.rear) {
			print("有后方镜头")
		}

		if UIImagePickerViewController.isFlashAvaliable(.rear) {
			print("有前方闪光灯")
		}

		if UIImagePickerViewController.isFlashAvaliable(.rear) {
			print("有后方闪光灯")
		}
	}
}

拍照与存储

UIImagePickerController提供了系统的拍照与管理功能。
让App有三种不同的来源获取照片:

  • .camera 代表开启相机让使用者拍照
  • .photoLibrary 代表照片来自已经存储的照片
  • .savedPhotosAlbum 代表照片来自某个特定的相簿,一般时Camera Roll

接下来介绍如何通过UIImagePickerController完成拍照功能。

  • 首先需要在App的info.plist中新增[Privacy - Camera Usage Description] 键值询问使用者是否同意授权App使用相机。以及[Privacy - Photo Library Additions Usage Description]询问使用者是否同意授权App存储照片。
  • 需要完成拍照功能的viewController需要遵循UINavigationController 和 UIImagePickerControlllerDelegate两个协议。
class ViewController: UIViewController, UINavigationController, UIImagePickerControllerDelegate {
	
}
  • 这里以点击屏幕开启拍照功能为例
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
	guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
		print("设备没有相机")
		return 
	}

	let imagePicker = UIImagePickerController()
	
	imagePicker.sourceType = .camera
	iamgePicker.delegate = self

	show(imagePicker, sender: self)
}
  • 开启相机后,使用者可以选择拍照或者取消,如果使用者拍摄了一张照片,imagePickerController(_:didFinshPickingMediaWithInfo:)函数会被调用
func imagePickerController(_ picker: UIImagePickerController, didFinshPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
	let image = info[.originalImage] as! UIImage //获取拍摄的照片

	UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
	dismiss(animated: true, completion: nil)
}

选择一张照片

在之前,如果要在iPad上开启照片选择器,Apple强制要求必须以popover小视窗的方式。但现在UIPopoverPresentationController不管当前设备是iPhone还是iPad都会开启popover模式并自调整成适合的样式。

@IBAction func onClick(_ sender: UIButton) {
	let imagePickerVC = UIImagePickerController()
	
	imagePickerVC.sourceType = .photoLibrary
	imagePickerVC.delegate = self

	imagePickerVC.modalPresentationStyle = .popover
	let popover = imagePickerVC.popoverPresentationController
		
	popover?.sourceView = sender //设定popover视图与哪一个view控件关联

	//下面两行处理popover试图的箭头位置
	popover?.sourceRect = sender.bounds
	popover?.permittedArrowDirections = self

	show(imagePickerVC, sender: self)
}

播放App内置的音乐

内置的音乐并不存储在设备中,如果删除App那么音乐也随App被删除了。
例:在一个ViewController中处理音乐的播放

  • 首先引入MediaPlayer框架
import MediaPlayer
  • 然后创建一个AVAudioPlayer类型的变量来处理音乐播放,再创建一个slider滑块显示与控制播放进度。
var audio: AVAudioPlayer?
  • 在viewDidLoad()函数中设置AVAudioSession,目的是注册一个回调函数,让音乐播放过程中有状态改变时(如有电话导致音乐中断),可以通过这个回调函数处理音乐的中断与恢复播放。
override func viewDidLoad() {
	super.viewDidLoad()		

	NotificationCenter.default.addObserver(
		self,
		selector: #selector(audioInterrupted(_:)),
		name: AVAudioSession.iterruptionNotification,
		object: nil
	)

	do {
		let url = Bundle.main.url(forResource: "music", withExtension: "mp3")
		try AVAudioPlayer(coutentsOf: url!)
		
		if audio != nil {
			if audio!.prepareToPlay() {
				print("开始播放音乐")
				audio!.play()
				
				slider.munimumValue = 0
				slider.maximumValue = Float(audio!.duration)
				slider.value = 0

				Timer.scheduleTimer(withTimeInterval: 1.0, repeats: true) {
				(timer) in
					self.ticker(timer: timer)	
				}
			}
		}
	} catch {
		print(error)
	}
}
  • 实现audioInterrupted(_:)函数,通过传进来的参数notifaction来判断音乐中断或者是中断结束。
@objc func audioInterrupted(_ notification: NSNotification) {
	gurad audio != nil, let userInfo = notification.userInfo else {
		return 
	}

	let type_tmp = userInfo[AVAudioSessiionInterruptionTypeKey] as! NSNumber
	let type = AVAudioSession.InterruptionType(rawValue: type_tmp.uintValue)
	
	switch type! {
		case .began: 
			print("音乐中断")
		case .ended: 
			print("音乐中断结束")

			let option_tmp = userInfo[AVAudioSessionInterruptionOptionKey] as! NSNumber
			let option = AVAudioSession.InterruptionOptions(rawValue: option_tmp.uintValue)

			if option == .shouldResume && audio!.prepareToPlay() {
				audio!.play()
			}
		@unknown default: 
			break
	}
}
  • 实现ticker(timer:)函数,每秒钟执行一次,更新slider的值,让进度值和播放进度一致。
func ticker(timer: timer) {
	slider.value = Float(audio!.currentTime)
	if !audio!.isPlaying {
		print("音乐结束")
		timer.invalidate()
	}
}
  • 实现sliderValueChanged(_:)函数,让使用者可以通过滑块控制音乐的播放进度
@IBAction func sliderValueChanged(_ sender: Any) {
	audio?.currentTime = Double(slider.value)
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-17 11:36:04  更:2022-01-17 11:36:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:03:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码