Commit 7d520e79 by Daniel Dahan

added exposeAtPoint with animation

parent d4b838ad
...@@ -30,6 +30,11 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre ...@@ -30,6 +30,11 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
public private(set) lazy var focusLayer: MaterialLayer = MaterialLayer() public private(set) lazy var focusLayer: MaterialLayer = MaterialLayer()
/** /**
:name: exposureLayer
*/
public private(set) lazy var exposureLayer: MaterialLayer = MaterialLayer()
/**
:name: switchCamerasButton :name: switchCamerasButton
*/ */
public var switchCamerasButton: MaterialButton? { public var switchCamerasButton: MaterialButton? {
...@@ -92,6 +97,7 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre ...@@ -92,6 +97,7 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
super.prepareView() super.prepareView()
preparePreviewView() preparePreviewView()
prepareFocusLayer() prepareFocusLayer()
prepareExposureLayer()
reloadView() reloadView()
} }
...@@ -150,6 +156,24 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre ...@@ -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 // :name: handleSwitchCameras
// //
...@@ -172,9 +196,20 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre ...@@ -172,9 +196,20 @@ public class BasicCaptureView : MaterialView, CaptureSessionDelegate, CapturePre
// //
private func prepareFocusLayer() { private func prepareFocusLayer() {
focusLayer.hidden = true 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.bounds = CGRectMake(0, 0, 150, 150)
focusLayer.cornerRadius = 75 focusLayer.cornerRadius = 75
previewView.layer.addSublayer(focusLayer) 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 { ...@@ -25,6 +25,11 @@ public protocol CapturePreviewViewDelegate : MaterialDelegate {
:name: capturePreviewViewDidTapToFocusAtPoint :name: capturePreviewViewDidTapToFocusAtPoint
*/ */
optional func capturePreviewViewDidTapToFocusAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint) optional func capturePreviewViewDidTapToFocusAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
/**
:name: capturePreviewViewDidTapToExposeAtPoint
*/
optional func capturePreviewViewDidTapToExposeAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
} }
public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
...@@ -33,6 +38,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { ...@@ -33,6 +38,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
// //
private var tapToFocusGesture: UITapGestureRecognizer? private var tapToFocusGesture: UITapGestureRecognizer?
//
// :name: tapToExposeGesture
//
private var tapToExposeGesture: UITapGestureRecognizer?
/** /**
:name: previewLayer :name: previewLayer
*/ */
...@@ -49,7 +59,7 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { ...@@ -49,7 +59,7 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
public var tapToFocusEnabled: Bool { public var tapToFocusEnabled: Bool {
didSet { didSet {
if tapToFocusEnabled { if tapToFocusEnabled {
prepareTapGesture(&tapToFocusGesture, selector: "handleTapToFocusGesture:") prepareTapGesture(&tapToFocusGesture, numberOfTapsRequired: 1, selector: "handleTapToFocusGesture:")
} else { } else {
removeTapGesture(&tapToFocusGesture) removeTapGesture(&tapToFocusGesture)
} }
...@@ -61,6 +71,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { ...@@ -61,6 +71,11 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
*/ */
public var tapToExposeEnabled: Bool { public var tapToExposeEnabled: Bool {
didSet { didSet {
if tapToExposeEnabled {
prepareTapGesture(&tapToExposeGesture, numberOfTapsRequired: 2, selector: "handleTapToExposeGesture:")
} else {
removeTapGesture(&tapToExposeGesture)
}
} }
} }
...@@ -135,6 +150,17 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { ...@@ -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 // :name: preparePreviewLayer
// //
private func preparePreviewLayer() { private func preparePreviewLayer() {
...@@ -149,14 +175,16 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate { ...@@ -149,14 +175,16 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
previewLayer.frame = visualLayer.bounds previewLayer.frame = visualLayer.bounds
previewLayer.position = CGPointMake(width / 2, height / 2) previewLayer.position = CGPointMake(width / 2, height / 2)
previewLayer.cornerRadius = visualLayer.cornerRadius previewLayer.cornerRadius = visualLayer.cornerRadius
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
} }
// //
// :name: prepareTapGesture // :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 = UITapGestureRecognizer(target: self, action: selector)
gesture!.delegate = self gesture!.delegate = self
gesture!.numberOfTapsRequired = numberOfTapsRequired
addGestureRecognizer(gesture!) addGestureRecognizer(gesture!)
} }
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
import UIKit import UIKit
import AVFoundation import AVFoundation
private var CaptureSessionAdjustingExposureContext: UInt8 = 1
public enum CaptureSessionPreset { public enum CaptureSessionPreset {
case High case High
} }
...@@ -131,6 +133,13 @@ public class CaptureSession : NSObject { ...@@ -131,6 +133,13 @@ public class CaptureSession : NSObject {
} }
/** /**
:name: cameraSupportsTapToExpose
*/
public var cameraSupportsTapToExpose: Bool {
return true == activeCamera?.exposurePointOfInterestSupported
}
/**
:name: focusMode :name: focusMode
*/ */
public var focusMode: AVCaptureFocusMode { public var focusMode: AVCaptureFocusMode {
...@@ -237,9 +246,9 @@ public class CaptureSession : NSObject { ...@@ -237,9 +246,9 @@ public class CaptureSession : NSObject {
*/ */
public func focusAtPoint(point: CGPoint) { public func focusAtPoint(point: CGPoint) {
var error: NSError? var error: NSError?
let device: AVCaptureDevice = activeCamera! if cameraSupportsTapToFocus && isFocusModeSupported(.AutoFocus) {
if device.focusPointOfInterestSupported && isFocusModeSupported(.AutoFocus) {
do { do {
let device: AVCaptureDevice = activeCamera!
try device.lockForConfiguration() try device.lockForConfiguration()
device.focusPointOfInterest = point device.focusPointOfInterest = point
device.focusMode = .AutoFocus device.focusMode = .AutoFocus
...@@ -255,6 +264,55 @@ public class CaptureSession : NSObject { ...@@ -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 // :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