如何将实时相机预览添加到UIView
我碰到一个问题,我试图解决在UIView边界,有什么办法来添加相机预览到UIView? 并在UIView(button,标签等)的顶部添加其他内容?
我尝试使用AVFoundation框架,但没有足够的文档Swift。
更新到SWIFT 3
你可以尝试这样的事情:
import UIKit import AVFoundation class ViewController: UIViewController{ var previewView : UIView! var boxView:UIView! let myButton: UIButton = UIButton() //Camera Capture requiered properties var videoDataOutput: AVCaptureVideoDataOutput! var videoDataOutputQueue: DispatchQueue! var previewLayer:AVCaptureVideoPreviewLayer! var captureDevice : AVCaptureDevice! let session = AVCaptureSession() override func viewDidLoad() { super.viewDidLoad() previewView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)) previewView.contentMode = UIViewContentMode.scaleAspectFit view.addSubview(previewView) //Add a view on top of the cameras' view boxView = UIView(frame: self.view.frame) myButton.frame = CGRect(x: 0, y: 0, width: 200, height: 40) myButton.backgroundColor = UIColor.red myButton.layer.masksToBounds = true myButton.setTitle("press me", for: UIControlState.normal) myButton.setTitleColor(UIColor.white, for: UIControlState.normal) myButton.layer.cornerRadius = 20.0 myButton.layer.position = CGPoint(x: self.view.frame.width/2, y:200) myButton.addTarget(self, action: #selector(self.onClickMyButton(sender:)), for: UIControlEvents.touchUpInside) view.addSubview(boxView) view.addSubview(myButton) self.setupAVCapture() } override var shouldAutorotate: Bool { if (UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft || UIDevice.current.orientation == UIDeviceOrientation.landscapeRight || UIDevice.current.orientation == UIDeviceOrientation.unknown) { return false } else { return true } } func onClickMyButton(sender: UIButton){ print("button pressed") } } // AVCaptureVideoDataOutputSampleBufferDelegate protocol and related methods extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate{ func setupAVCapture(){ session.sessionPreset = AVCaptureSessionPreset640x480 guard let device = AVCaptureDevice .defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back) else{ return } captureDevice = device beginSession() } func beginSession(){ var err : NSError? = nil var deviceInput:AVCaptureDeviceInput? do { deviceInput = try AVCaptureDeviceInput(device: captureDevice) } catch let error as NSError { err = error deviceInput = nil } if err != nil { print("error: \(err?.localizedDescription)"); } if self.session.canAddInput(deviceInput){ self.session.addInput(deviceInput); } videoDataOutput = AVCaptureVideoDataOutput() videoDataOutput.alwaysDiscardsLateVideoFrames=true videoDataOutputQueue = DispatchQueue(label: "VideoDataOutputQueue") videoDataOutput.setSampleBufferDelegate(self, queue:self.videoDataOutputQueue) if session.canAddOutput(self.videoDataOutput){ session.addOutput(self.videoDataOutput) } videoDataOutput.connection(withMediaType: AVMediaTypeVideo).isEnabled = true self.previewLayer = AVCaptureVideoPreviewLayer(session: self.session) self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspect let rootLayer :CALayer = self.previewView.layer rootLayer.masksToBounds = true self.previewLayer.frame = rootLayer.bounds rootLayer.addSublayer(self.previewLayer) session.startRunning() } func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { // do stuff here } // clean up AVCapture func stopCamera(){ session.stopRunning() } }
在这里我使用一个叫做previewView的UIView
来启动摄像头,然后添加一个名为boxView的新的UIView
它在previewView之上。 我添加一个UIButton
到boxView
重要
请记住,在iOS 10及更高版本中,您需要先向用户请求权限才能访问摄像机。 您可以通过在应用程序的
Info.plist
添加一个用法键和一个用途string来实现这一点,因为如果您未能声明使用情况,则您的应用程序在首次访问时会崩溃。
以下是显示相机访问请求的截图
Swift 3:
@IBOutlet weak var cameraContainerView:UIView! var imagePickers:UIImagePickerController?
在ViewDidLoad上:
override func viewDidLoad() { super.viewDidLoad() addImagePickerToContainerView() }
将相机预览添加到容器视图:
func addImagePickerToContainerView(){ imagePickers = UIImagePickerController() if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerControllerCameraDevice.front) { imagePickers?.delegate = self imagePickers?.sourceType = UIImagePickerControllerSourceType.camera //add as a childviewcontroller addChildViewController(imagePickers!) // Add the child's View as a subview self.cameraContainerView.addSubview((imagePickers?.view)!) imagePickers?.view.frame = cameraContainerView.bounds imagePickers?.allowsEditing = false imagePickers?.showsCameraControls = false imagePickers?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] } }
在自定义button操作上:
@IBAction func cameraButtonPressed(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.camera){ imagePickers?.takePicture() } else{ //Camera not available. } }