Commit 7d520e79 by Daniel Dahan

added exposeAtPoint with animation

parent d4b838ad
......@@ -30,6 +30,11 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
public private(set) lazy var focusLayer: MaterialLayer = MaterialLayer()
/**
:name: exposureLayer
*/
public private(set) lazy var exposureLayer: MaterialLayer = MaterialLayer()
/**
:name: switchCamerasButton
*/
public var switchCamerasButton: MaterialButton? {
......@@ -92,6 +97,7 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
super.prepareView()
preparePreviewView()
prepareFocusLayer()
prepareExposureLayer()
reloadView()
}
......@@ -150,6 +156,24 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
}
}
/**
:name: capturePreviewViewDidTapToExposeAtPoint
*/
public func capturePreviewViewDidTapToExposeAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint) {
MaterialAnimation.animationDisabled {
self.exposureLayer.position = point
self.exposureLayer.hidden = false
}
MaterialAnimation.animateWithDuration(0.25, animations: {
self.exposureLayer.transform = CATransform3DMakeScale(0, 0, 1)
}) {
MaterialAnimation.animationDisabled {
self.exposureLayer.hidden = true
self.exposureLayer.transform = CATransform3DIdentity
}
}
}
//
// :name: handleSwitchCameras
//
......@@ -172,9 +196,20 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
//
private func prepareFocusLayer() {
focusLayer.hidden = true
focusLayer.backgroundColor = MaterialColor.white.colorWithAlphaComponent(0.25).CGColor
focusLayer.backgroundColor = MaterialColor.blue.base.colorWithAlphaComponent(0.25).CGColor
focusLayer.bounds = CGRectMake(0, 0, 150, 150)
focusLayer.cornerRadius = 75
previewView.layer.addSublayer(focusLayer)
}
//
// :name: prepareExposureLayer
//
private func prepareExposureLayer() {
exposureLayer.hidden = true
exposureLayer.backgroundColor = MaterialColor.red.base.colorWithAlphaComponent(0.25).CGColor
exposureLayer.bounds = CGRectMake(0, 0, 150, 150)
exposureLayer.cornerRadius = 75
previewView.layer.addSublayer(exposureLayer)
}
}
\ No newline at end of file
......@@ -25,6 +25,11 @@ public protocol CapturePreviewViewDelegate : MaterialDelegate {
:name: capturePreviewViewDidTapToFocusAtPoint
*/
optional func capturePreviewViewDidTapToFocusAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
/**
:name: capturePreviewViewDidTapToExposeAtPoint
*/
optional func capturePreviewViewDidTapToExposeAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
}
public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
......@@ -33,6 +38,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
//
private var tapToFocusGesture: UITapGestureRecognizer?
//
// :name: tapToExposeGesture
//
private var tapToExposeGesture: UITapGestureRecognizer?
/**
:name: previewLayer
*/
......@@ -49,7 +59,7 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
public var tapToFocusEnabled: Bool {
didSet {
if tapToFocusEnabled {
prepareTapGesture(&tapToFocusGesture, selector: "handleTapToFocusGesture:")
prepareTapGesture(&tapToFocusGesture, numberOfTapsRequired: 1, selector: "handleTapToFocusGesture:")
} else {
removeTapGesture(&tapToFocusGesture)
}
......@@ -61,6 +71,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
*/
public var tapToExposeEnabled: Bool {
didSet {
if tapToExposeEnabled {
prepareTapGesture(&tapToExposeGesture, numberOfTapsRequired: 2, selector: "handleTapToExposeGesture:")
} else {
removeTapGesture(&tapToExposeGesture)
}
}
}
......@@ -135,6 +150,17 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
}
//
// :name: handleTapToExposeGesture
//
internal func handleTapToExposeGesture(recognizer: UITapGestureRecognizer) {
if tapToExposeEnabled && captureSession.cameraSupportsTapToExpose {
let point: CGPoint = recognizer.locationInView(self)
captureSession.exposeAtPoint(captureDevicePointOfInterestForPoint(point))
(delegate as? CapturePreviewViewDelegate)?.capturePreviewViewDidTapToExposeAtPoint?(self, point: point)
}
}
//
// :name: preparePreviewLayer
//
private func preparePreviewLayer() {
......@@ -149,14 +175,16 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
previewLayer.frame = visualLayer.bounds
previewLayer.position = CGPointMake(width / 2, height / 2)
previewLayer.cornerRadius = visualLayer.cornerRadius
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
}
//
// :name: prepareTapGesture
//
private func prepareTapGesture(inout gesture: UITapGestureRecognizer?, selector: Selector) {
private func prepareTapGesture(inout gesture: UITapGestureRecognizer?, numberOfTapsRequired: Int, selector: Selector) {
gesture = UITapGestureRecognizer(target: self, action: selector)
gesture!.delegate = self
gesture!.numberOfTapsRequired = numberOfTapsRequired
addGestureRecognizer(gesture!)
}
......
......@@ -19,6 +19,8 @@
import UIKit
import AVFoundation
private var CaptureSessionAdjustingExposureContext: UInt8 = 1
public enum CaptureSessionPreset {
case High
}
......@@ -131,6 +133,13 @@ public class CaptureSession : NSObject {
}
/**
:name: cameraSupportsTapToExpose
*/
public var cameraSupportsTapToExpose: Bool {
return true == activeCamera?.exposurePointOfInterestSupported
}
/**
:name: focusMode
*/
public var focusMode: AVCaptureFocusMode {
......@@ -237,9 +246,9 @@ public class CaptureSession : NSObject {
*/
public func focusAtPoint(point: CGPoint) {
var error: NSError?
let device: AVCaptureDevice = activeCamera!
if device.focusPointOfInterestSupported && isFocusModeSupported(.AutoFocus) {
if cameraSupportsTapToFocus && isFocusModeSupported(.AutoFocus) {
do {
let device: AVCaptureDevice = activeCamera!
try device.lockForConfiguration()
device.focusPointOfInterest = point
device.focusMode = .AutoFocus
......@@ -255,6 +264,55 @@ public class CaptureSession : NSObject {
}
}
/**
:name: exposeAtPoint
*/
public func exposeAtPoint(point: CGPoint) {
var error: NSError?
if cameraSupportsTapToExpose && isExposureModeSupported(.ContinuousAutoExposure) {
do {
let device: AVCaptureDevice = activeCamera!
try device.lockForConfiguration()
device.exposurePointOfInterest = point
device.exposureMode = .ContinuousAutoExposure
if device.isExposureModeSupported(.Locked) {
device.addObserver(self, forKeyPath: "adjustingExposure", options: .New, context: &CaptureSessionAdjustingExposureContext)
}
device.unlockForConfiguration()
} catch let e as NSError {
error = e
}
} else {
error = NSError(domain: "[MaterialKit Error: Unsupported exposeAtPoint.]", code: 0, userInfo: nil)
}
if let e: NSError = error {
delegate?.captureSessionFailedWithError?(self, error: e)
}
}
/**
:name: observeValueForKeyPath
*/
public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if context == &CaptureSessionAdjustingExposureContext {
let device: AVCaptureDevice = object as! AVCaptureDevice
if !device.adjustingExposure && device.isExposureModeSupported(.Locked) {
object!.removeObserver(self, forKeyPath: "adjustingExposure", context: &CaptureSessionAdjustingExposureContext)
dispatch_async(dispatch_get_main_queue()) {
do {
try device.lockForConfiguration()
device.exposureMode = .Locked
device.unlockForConfiguration()
} catch let e as NSError {
self.delegate?.captureSessionFailedWithError?(self, error: e)
}
}
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}
//
// :name: prepareSession
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment