iOS 10自定義相機(jī)功能
本文實(shí)例為大家分享了iOS 10自定義相機(jī)功能的具體代碼,供大家參考,具體內(nèi)容如下
直接上代碼
//
// TGCameraVC.swift
// TGPhotoPicker
//
// Created by targetcloud on 2017/7/25.
// Copyright © 2017年 targetcloud. All rights reserved.
//
import UIKit
import AVFoundation
import Photos
@available(iOS 10.0, *)
class TGCameraVC: UIViewController {
var callbackPicutureData: ((Data?) -> ())?
private var device: AVCaptureDevice?
private var input: AVCaptureDeviceInput?
private var imageOutput: AVCapturePhotoOutput?
private var session: AVCaptureSession?
private var previewLayer: AVCaptureVideoPreviewLayer?
fileprivate var showImageContainerView: UIView?
fileprivate var showImageView: UIImageView?
fileprivate var picData: Data?
private var flashMode: AVCaptureFlashMode = .auto
private weak var flashButton: UIButton?
override func viewDidLoad() {
super.viewDidLoad()
setupCamera()
setupUI()
if #available(iOS 9.0, *) {
let isVCBased = Bundle.main.infoDictionary?["UIViewControllerBasedStatusBarAppearance"] as? Bool ?? false
if !isVCBased{
UIApplication.shared.setStatusBarHidden(false, with: .none)
}
}else {
UIApplication.shared.statusBarStyle = .lightContent
UIApplication.shared.setStatusBarHidden(false, with: .none)
}
}
override var prefersStatusBarHidden: Bool{
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
private func setupCamera() {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { success in
if !success {
let alertVC = UIAlertController(title: TGPhotoPickerConfig.shared.cameraUsage, message: TGPhotoPickerConfig.shared.cameraUsageTip, preferredStyle: .actionSheet)
alertVC.addAction(UIAlertAction(title: TGPhotoPickerConfig.shared.confirmTitle, style: .default, handler: nil))
self.present(alertVC, animated: true, completion: nil)
}
}
device = cameraWithPosistion(.back)
input = try? AVCaptureDeviceInput(device: device)
guard input != nil else {
return
}
imageOutput = AVCapturePhotoOutput()
session = AVCaptureSession()
session?.beginConfiguration()
session?.sessionPreset = TGPhotoPickerConfig.shared.sessionPreset
if session!.canAddInput(input) {
session!.addInput(input)
}
if session!.canAddOutput(imageOutput) {
session!.addOutput(imageOutput)
}
previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer?.frame = view.bounds
previewLayer?.videoGravity = TGPhotoPickerConfig.shared.videoGravity
view.layer.addSublayer(previewLayer!)
session?.commitConfiguration()
session?.startRunning()
}
private func cameraWithPosistion(_ position: AVCaptureDevicePosition) -> AVCaptureDevice {
let type = AVCaptureDeviceType(rawValue: TGPhotoPickerConfig.shared.captureDeviceType.rawValue)
return AVCaptureDevice.defaultDevice(withDeviceType: type, mediaType: AVMediaTypeVideo, position: position)
}
private func setupUI() {
let takeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH))
takeButton.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height - TGPhotoPickerConfig.shared.buttonEdge.bottom)
takeButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH).border(width: 3).border(color: .white).color(.clear).corner(radius: TGPhotoPickerConfig.shared.takeWH / 2).image +
UIImage.size(width: TGPhotoPickerConfig.shared.takeWH - 10, height: TGPhotoPickerConfig.shared.takeWH - 10).color(UIColor(white: 0.95, alpha: 1) ).corner(radius: (TGPhotoPickerConfig.shared.takeWH - 10) / 2).image, for: .normal)
takeButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH, height: TGPhotoPickerConfig.shared.takeWH).border(width: 3).border(color: .white).color(.clear).corner(radius: TGPhotoPickerConfig.shared.takeWH / 2).image +
UIImage.size(width: TGPhotoPickerConfig.shared.takeWH - 10, height: TGPhotoPickerConfig.shared.takeWH - 10).color(UIColor(white: 0.8, alpha: 1) ).corner(radius: (TGPhotoPickerConfig.shared.takeWH - 10) / 2).image, for: .highlighted)
takeButton.addTarget(self, action: #selector(takePhotoAction), for: .touchUpInside)
view.addSubview(takeButton)
let cameraChangeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.6, height: TGPhotoPickerConfig.shared.takeWH * 0.6))
cameraChangeButton.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("camera"), for: .normal)
cameraChangeButton.center = CGPoint(x: UIScreen.main.bounds.width - TGPhotoPickerConfig.shared.buttonEdge.right, y: takeButton.center.y)
cameraChangeButton.addTarget(self, action: #selector(changeCameraPositionAction), for: .touchUpInside)
cameraChangeButton.contentMode = .scaleAspectFit
view.addSubview(cameraChangeButton)
let flashChangeButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.5, height: TGPhotoPickerConfig.shared.takeWH * 0.5))
flashChangeButton.center = CGPoint(x: cameraChangeButton.center.x, y: TGPhotoPickerConfig.shared.buttonEdge.top)
flashChangeButton.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashauto"), for: .normal)
flashChangeButton.addTarget(self, action: #selector(flashChangeAction), for: .touchUpInside)
flashChangeButton.contentMode = .scaleAspectFit
flashButton = flashChangeButton
view.addSubview(flashChangeButton)
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.4, height: TGPhotoPickerConfig.shared.takeWH * 0.4))
backButton.center = CGPoint(x: TGPhotoPickerConfig.shared.buttonEdge.left , y: flashChangeButton.center.y)
backButton.setImage(UIImage.size(width: TGPhotoPickerConfig.shared.takeWH * 0.4, height: TGPhotoPickerConfig.shared.takeWH * 0.4)
.corner(radius: TGPhotoPickerConfig.shared.takeWH * 0.2)
.color(.clear)
.border(color: UIColor.white.withAlphaComponent(0.7))
.border(width: TGPhotoPickerConfig.shared.isShowBorder ? TGPhotoPickerConfig.shared.checkboxLineW : 0)
.image
.with({ context in
context.setLineCap(.round)
UIColor.white.setStroke()
context.setLineWidth(TGPhotoPickerConfig.shared.checkboxLineW)
let WH = TGPhotoPickerConfig.shared.takeWH * 0.4
context.move(to: CGPoint(x: WH * 0.6, y: WH * 0.2))
context.addLine(to: CGPoint(x: WH * 0.35, y: WH * 0.5))
context.move(to: CGPoint(x: WH * 0.35, y: WH * 0.5))
context.addLine(to: CGPoint(x: WH * 0.6, y: WH * 0.8))
context.strokePath()
}), for: .normal)
backButton.contentMode = .scaleAspectFit
backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside)
view.addSubview(backButton)
showImageContainerView = UIView(frame: view.bounds)
showImageContainerView?.backgroundColor = TGPhotoPickerConfig.shared.previewBGColor
view.addSubview(showImageContainerView!)
let height = showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH - TGPhotoPickerConfig.shared.buttonEdge.bottom - TGPhotoPickerConfig.shared.previewPadding * 2
showImageView = UIImageView(frame: CGRect(x: TGPhotoPickerConfig.shared.previewPadding, y: TGPhotoPickerConfig.shared.previewPadding * 2, width: showImageContainerView!.bounds.width - 2 * TGPhotoPickerConfig.shared.previewPadding, height: height))
showImageView?.contentMode = .scaleAspectFit
showImageContainerView?.addSubview(showImageView!)
showImageContainerView?.isHidden = true
let giveupButton = createImageOperatorButton(nil, CGPoint(x: TGPhotoPickerConfig.shared.takeWH * 1.5, y: showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH * 1.5), TGPhotoPickerConfig.shared.getCheckboxImage(true, true, .circle, TGPhotoPickerConfig.shared.takeWH * 0.7).unselect)
giveupButton.addTarget(self, action: #selector(giveupImageAction), for: .touchUpInside)
showImageContainerView?.addSubview(giveupButton)
let ensureButton = createImageOperatorButton(nil, CGPoint(x: showImageContainerView!.bounds.width - TGPhotoPickerConfig.shared.takeWH * 1.5, y: showImageContainerView!.bounds.height - TGPhotoPickerConfig.shared.takeWH * 1.5), TGPhotoPickerConfig.shared.getCheckboxImage(true, false, .circle, TGPhotoPickerConfig.shared.takeWH * 0.7).select)
ensureButton.addTarget(self, action: #selector(useImageAction), for: .touchUpInside)
showImageContainerView?.addSubview(ensureButton)
}
private func createImageOperatorButton(_ title: String?, _ center: CGPoint, _ img: UIImage?) -> UIButton {
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: TGPhotoPickerConfig.shared.takeWH * 0.7, height: TGPhotoPickerConfig.shared.takeWH * 0.7))
btn.center = center
btn.setTitle(title, for: .normal)
btn.setImage(img, for: .normal)
btn.contentMode = .scaleAspectFit
return btn
}
@objc private func flashChangeAction() {
switch flashMode {
case .auto:
flashMode = .on
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flash"), for: .normal)
case .on:
flashMode = .off
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashno"), for: .normal)
case .off:
flashMode = .auto
flashButton?.setImage(TGPhotoPickerConfig.getImageNo2x3xSuffix("flashauto"), for: .normal)
}
}
@objc private func backAction() {
dismiss(animated: true, completion: nil)
}
@objc private func takePhotoAction() {
let connection = imageOutput?.connection(withMediaType: AVMediaTypeVideo)
guard connection != nil else {
return
}
let photoSettings = AVCapturePhotoSettings()
photoSettings.flashMode = flashMode
imageOutput?.capturePhoto(with: photoSettings, delegate: self)
}
@objc private func changeCameraPositionAction() {
let animation = CATransition()
animation.duration = 0.5
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.type = TGPhotoPickerConfig.shared.transitionType
let newDevice: AVCaptureDevice!
let newInput: AVCaptureDeviceInput?
let position = input?.device.position
if position == .front {
newDevice = cameraWithPosistion(.back)
animation.subtype = kCATransitionFromLeft
} else {
newDevice = cameraWithPosistion(.front)
animation.subtype = kCATransitionFromRight
}
newInput = try? AVCaptureDeviceInput(device: newDevice)
guard newInput != nil else{
return
}
previewLayer?.add(animation, forKey: nil)
session?.beginConfiguration()
session?.removeInput(input)
if session!.canAddInput(newInput) {
session?.addInput(newInput!)
input = newInput
} else {
session?.addInput(input)
}
session?.commitConfiguration()
}
@objc private func giveupImageAction() {
showImageView?.image = UIImage()
showImageContainerView?.isHidden = true
}
@objc private func useImageAction() {
callbackPicutureData?(picData)
dismiss(animated: true, completion: nil)
}
}
@available(iOS 10.0, *)
extension TGCameraVC: AVCapturePhotoCaptureDelegate {
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
if error != nil {
print("error = \(String(describing: error?.localizedDescription))")
} else {
if let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer){
picData = imageData
showImageContainerView?.isHidden = false
showImageView?.image = UIImage(data: imageData)
if TGPhotoPickerConfig.shared.saveImageToPhotoAlbum{
self.saveImageToPhotoAlbum(UIImage(data: imageData)!)
}
}
}
}
fileprivate func saveImageToPhotoAlbum(_ savedImage:UIImage){
UIImageWriteToSavedPhotosAlbum(savedImage, self, #selector(imageDidFinishSavingWithErrorContextInfo), nil)
}
@objc fileprivate func imageDidFinishSavingWithErrorContextInfo(image:UIImage,error:NSError?,contextInfo:UnsafeMutableRawPointer?){
if canUseAlbum(){
let msg = (error != nil) ? TGPhotoPickerConfig.shared.saveImageFailTip : TGPhotoPickerConfig.shared.saveImageSuccessTip
let alert = UIAlertView(title: TGPhotoPickerConfig.shared.saveImageTip, message: msg, delegate: self, cancelButtonTitle: TGPhotoPickerConfig.shared.confirmTitle)
alert.show()
}
}
fileprivate func canUseAlbum()-> Bool{
if PHPhotoLibrary.authorizationStatus() != PHAuthorizationStatus.authorized {
let alertView = UIAlertView(title: TGPhotoPickerConfig.shared.PhotoLibraryUsage, message: TGPhotoPickerConfig.shared.PhotoLibraryUsageTip, delegate: nil, cancelButtonTitle: TGPhotoPickerConfig.shared.confirmTitle, otherButtonTitles: TGPhotoPickerConfig.shared.cancelTitle)
alertView.tag = TGPhotoPickerConfig.shared.alertViewTag
alertView.show()
return false
}else{
return true
}
}
}
效果如下

完整使用DEMO見(jiàn):點(diǎn)擊打開(kāi)鏈接
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- iOS開(kāi)發(fā)技巧之自定義相機(jī)
- iOS自定義相機(jī)實(shí)現(xiàn)拍照、錄制視頻
- iOS框架AVFoundation實(shí)現(xiàn)相機(jī)拍照、錄制視頻
- iOS仿微信相機(jī)拍照、視頻錄制功能
- IOS打開(kāi)照相機(jī)與本地相冊(cè)選擇圖片實(shí)例詳解
- iOS開(kāi)發(fā)-自定義相機(jī)實(shí)例(仿微信)
- iOS開(kāi)發(fā)-調(diào)用系統(tǒng)相機(jī)和相冊(cè)獲取照片示例
- IOS10 相冊(cè)相機(jī)閃退bug解決辦法
- IOS打開(kāi)系統(tǒng)相機(jī)的閃光燈
- iOS自定義相機(jī)功能
相關(guān)文章
使用Xcode為iOS應(yīng)用項(xiàng)目創(chuàng)建PCH文件的方法及應(yīng)用示例
這篇文章主要介紹了使用Xcode為iOS應(yīng)用項(xiàng)目創(chuàng)建PCH文件的方法及應(yīng)用示例,PCH文件可以保留應(yīng)用的很多的基礎(chǔ)設(shè)置信息以供復(fù)用,需要的朋友可以參考下2016-03-03
iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于iOS中wkwebView內(nèi)存泄漏與循環(huán)引用問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
IOS 開(kāi)發(fā)之自定義按鈕實(shí)現(xiàn)文字圖片位置隨意定制
這篇文章主要介紹了IOS 開(kāi)發(fā)之自定義按鈕實(shí)現(xiàn)文字圖片位置隨意定制的相關(guān)資料,這里附有實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-12-12
iOS動(dòng)畫(huà)解析之圓球加載動(dòng)畫(huà)XLBallLoading的實(shí)現(xiàn)
加載動(dòng)畫(huà)對(duì)大家來(lái)說(shuō)都不陌生,我們?cè)谄綍r(shí)都會(huì)遇見(jiàn),開(kāi)發(fā)中也必不可少,所以下面這篇文章主要給大家介紹了關(guān)于iOS動(dòng)畫(huà)解析之圓球加載動(dòng)畫(huà)XLBallLoading實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-11-11
IOS文件的簡(jiǎn)單讀寫(xiě)實(shí)例詳解
這篇文章主要介紹了IOS文件的簡(jiǎn)單讀寫(xiě)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07
iOS 無(wú)卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn)
這篇文章主要介紹了iOS 無(wú)卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
iOS安全防護(hù)系列之字符串及系統(tǒng)函數(shù)隱藏詳解
這篇文章主要給大家介紹了關(guān)于iOS安全防護(hù)系列之字符串及系統(tǒng)函數(shù)隱藏的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
iOS中使用NSURLConnection處理HTTP同步與異步請(qǐng)求
NSURLConnection的作用現(xiàn)在已經(jīng)基本被NSURLSession所取代,所以我們簡(jiǎn)單了解下iOS中使用NSURLConnection處理HTTP同步與異步請(qǐng)求的方法即可:2016-07-07

