Commit d3b4ccc1 by Daniel Dahan

decoupling views for CaptureView

parent 61a63660
......@@ -25,32 +25,20 @@ enum CaptureMode {
case Video
}
class ViewController: UIViewController, CapturePreviewViewDelegate, CaptureSessionDelegate {
private lazy var navigationBarView: NavigationBarView = NavigationBarView()
private lazy var captureView: CaptureView = CaptureView()
private lazy var cameraButton: FlatButton = FlatButton()
private lazy var captureButton: FabButton = FabButton()
private lazy var videoButton: FlatButton = FlatButton()
private lazy var switchCameraButton: FlatButton = FlatButton()
private lazy var flashButton: FlatButton = FlatButton()
private lazy var closeButton: FlatButton = FlatButton()
private lazy var captureMode: CaptureMode = .Video
private var timer: NSTimer?
class ViewController: UIViewController, CaptureViewDelegate, CaptureSessionDelegate {
private lazy var cameraView: CameraView = CameraView()
override func viewDidLoad() {
super.viewDidLoad()
prepareView()
prepareCaptureView()
prepareNavigationBarView()
prepareCaptureButton()
prepareCameraButton()
prepareVideoButton()
prepareCloseButton()
prepareSwitchCameraButton()
prepareFlashButton()
prepareCameraView()
}
private func prepareCameraView() {
cameraView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cameraView)
MaterialLayout.alignToParent(view, child: cameraView)
}
/**
......@@ -61,246 +49,6 @@ class ViewController: UIViewController, CapturePreviewViewDelegate, CaptureSessi
}
/**
:name: prepareNavigationBarView
*/
private func prepareNavigationBarView() {
navigationBarView.backgroundColor = MaterialColor.black.colorWithAlphaComponent(0.3)
navigationBarView.shadowDepth = .None
navigationBarView.statusBarStyle = .LightContent
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "00:00:00"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.regularWithSize(20)
navigationBarView.titleLabel = titleLabel
navigationBarView.titleLabelInsetsRef.left = 64
// Detail label
let detailLabel: UILabel = UILabel()
detailLabel.text = "Stopped"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
detailLabel.font = RobotoFont.regularWithSize(12)
navigationBarView.detailLabel = detailLabel
navigationBarView.detailLabelInsetsRef.left = 64
view.addSubview(navigationBarView)
navigationBarView.leftButtons = [closeButton]
navigationBarView.rightButtons = [switchCameraButton, flashButton]
}
/**
:name: prepareCaptureButton
*/
private func prepareCaptureButton() {
captureButton.pulseColor = MaterialColor.white
captureButton.pulseFill = true
captureButton.backgroundColor = MaterialColor.red.darken1.colorWithAlphaComponent(0.3)
captureButton.borderWidth = .Border2
captureButton.borderColor = MaterialColor.white
captureButton.shadowDepth = .None
captureButton.addTarget(self, action: "handleCaptureButton:", forControlEvents: .TouchUpInside)
view.addSubview(captureButton)
captureButton.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomRight(view, child: captureButton, bottom: 24, right: (view.bounds.width - 72) / 2)
MaterialLayout.size(view, child: captureButton, width: 72, height: 72)
}
/**
:name: prepareCameraButton
*/
private func prepareCameraButton() {
let img4: UIImage? = UIImage(named: "ic_photo_camera_white_36pt")
cameraButton.pulseColor = nil
cameraButton.setImage(img4, forState: .Normal)
cameraButton.setImage(img4, forState: .Highlighted)
cameraButton.addTarget(self, action: "handleCameraButton:", forControlEvents: .TouchUpInside)
view.addSubview(cameraButton)
cameraButton.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomLeft(view, child: cameraButton, bottom: 24, left: 24)
}
/**
:name: prepareVideoButton
*/
private func prepareVideoButton() {
let img5: UIImage? = UIImage(named: "ic_videocam_white_36pt")
videoButton.pulseColor = nil
videoButton.setImage(img5, forState: .Normal)
videoButton.setImage(img5, forState: .Highlighted)
videoButton.addTarget(self, action: "handleVideoButton:", forControlEvents: .TouchUpInside)
view.addSubview(videoButton)
videoButton.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomRight(view, child: videoButton, bottom: 24, right: 24)
}
/**
:name: prepareCloseButton
*/
private func prepareCloseButton() {
let img: UIImage? = UIImage(named: "ic_close_white")
closeButton.pulseColor = MaterialColor.white
closeButton.pulseFill = true
closeButton.setImage(img, forState: .Normal)
closeButton.setImage(img, forState: .Highlighted)
}
/**
:name: prepareSwitchCameraButton
*/
private func prepareSwitchCameraButton() {
let img: UIImage? = UIImage(named: "ic_camera_front_white")
switchCameraButton.pulseColor = MaterialColor.white
switchCameraButton.pulseFill = true
switchCameraButton.setImage(img, forState: .Normal)
switchCameraButton.setImage(img, forState: .Highlighted)
switchCameraButton.addTarget(self, action: "handleSwitchCameraButton:", forControlEvents: .TouchUpInside)
}
/**
:name: prepareFlashButton
*/
private func prepareFlashButton() {
captureView.captureSession.flashMode = .Auto
let img: UIImage? = UIImage(named: "ic_flash_auto_white")
flashButton.pulseColor = MaterialColor.white
flashButton.pulseFill = true
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
flashButton.addTarget(self, action: "handleFlashButton:", forControlEvents: .TouchUpInside)
}
/**
:name: prepareCaptureView
*/
private func prepareCaptureView() {
captureView.captureSession.delegate = self
captureView.captureButton = captureButton
captureView.flashButton = flashButton
captureView.switchCamerasButton = switchCameraButton
view.addSubview(captureView)
captureView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: captureView)
}
/**
:name: handleCaptureButton
*/
internal func handleCaptureButton(button: UIButton) {
if .Photo == captureMode {
captureView.captureSession.captureStillImage()
} else if .Video == captureMode {
if captureView.captureSession.isRecording {
captureView.captureSession.stopRecording()
stopTimer()
} else {
captureView.captureSession.startRecording()
startTimer()
}
}
}
/**
:name: handleSwitchCameraButton
*/
internal func handleSwitchCameraButton(button: UIButton) {
var img: UIImage?
if .Back == captureView.captureSession.cameraPosition {
img = UIImage(named: "ic_camera_rear_white")
captureView.captureSession.switchCameras()
} else if .Front == captureView.captureSession.cameraPosition {
img = UIImage(named: "ic_camera_front_white")
captureView.captureSession.switchCameras()
}
switchCameraButton.setImage(img, forState: .Normal)
switchCameraButton.setImage(img, forState: .Highlighted)
}
/**
:name: handleFlashButton
*/
internal func handleFlashButton(button: UIButton) {
if .Back == captureView.captureSession.cameraPosition {
var img: UIImage?
switch captureView.captureSession.flashMode {
case .Off:
img = UIImage(named: "ic_flash_on_white")
captureView.captureSession.flashMode = .On
case .On:
img = UIImage(named: "ic_flash_auto_white")
captureView.captureSession.flashMode = .Auto
case .Auto:
img = UIImage(named: "ic_flash_off_white")
captureView.captureSession.flashMode = .Off
}
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
}
}
/**
:name: handleCameraButton
*/
func handleCameraButton(button: UIButton) {
captureButton.backgroundColor = MaterialColor.blue.darken1.colorWithAlphaComponent(0.3)
captureMode = .Photo
navigationBarView.titleLabel!.text = ""
navigationBarView.detailLabel!.text = ""
}
/**
:name: handleVideoButton
*/
func handleVideoButton(button: UIButton) {
captureButton.backgroundColor = MaterialColor.red.darken1.colorWithAlphaComponent(0.3)
captureMode = .Video
navigationBarView.titleLabel!.text = "00:00:00"
navigationBarView.detailLabel!.text = "Stopped"
}
/**
:name: captureSessionFailedWithError
*/
func captureSessionFailedWithError(capture: CaptureSession, error: NSError) {
print(error)
}
/**
:name: captureSessionWillSwitchCameras
*/
func captureSessionWillSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
if .Back == position {
let img: UIImage? = UIImage(named: "ic_flash_off_white")
captureView.captureSession.flashMode = .Off
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
}
}
/**
:name: captureSessionDidSwitchCameras
*/
func captureSessionDidSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
if .Back == position {
let img: UIImage? = UIImage(named: "ic_flash_auto_white")
captureView.captureSession.flashMode = .Auto
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
}
}
/**
:name: captureStillImageAsynchronously
*/
func captureStillImageAsynchronously(capture: CaptureSession, image: UIImage) {
......@@ -327,41 +75,4 @@ class ViewController: UIViewController, CapturePreviewViewDelegate, CaptureSessi
func captureDidFinishRecordingToOutputFileAtURL(capture: CaptureSession, captureOutput: AVCaptureFileOutput, outputFileURL: NSURL, fromConnections connections: [AnyObject], error: NSError!) {
print("Capture Stopped Recording \(outputFileURL)")
}
/**
:name: startTimer
*/
func startTimer() {
timer?.invalidate()
timer = NSTimer(timeInterval: 0.5, target: self, selector: "updateTimer", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes)
navigationBarView.detailLabel!.textColor = MaterialColor.red.accent1
captureButton.backgroundColor = MaterialColor.red.darken4.colorWithAlphaComponent(0.3)
}
/**
:name: updateTimer
*/
func updateTimer() {
let duration: CMTime = captureView.captureSession.recordedDuration
let time: Double = CMTimeGetSeconds(duration)
let hours: Int = Int(time / 3600)
let minutes: Int = Int((time / 60) % 60)
let seconds: Int = Int(time % 60)
navigationBarView.titleLabel!.text = String(format: "%02i:%02i:%02i", arguments: [hours, minutes, seconds])
navigationBarView.detailLabel!.text = "Recording"
}
/**
:name: stopTimer
*/
func stopTimer() {
timer?.invalidate()
timer = nil
navigationBarView.titleLabel!.text = "00:00:00"
navigationBarView.detailLabel!.text = "Stopped"
navigationBarView.detailLabel!.textColor = MaterialColor.white
captureButton.backgroundColor = MaterialColor.red.darken1.colorWithAlphaComponent(0.3)
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<scenes>
<!--View Controller-->
......@@ -19,21 +19,17 @@
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="g8F-Xx-oIC" customClass="RaisedButton" customModule="MaterialKit">
<rect key="frame" x="107" y="207" width="200" height="65"/>
<animations/>
<state key="normal" title="Button"/>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KGx-lb-zep" customClass="FlatButton" customModule="MaterialKit">
<rect key="frame" x="107" y="107" width="200" height="65"/>
<animations/>
<state key="normal" title="Button"/>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZEH-7f-aTd" customClass="FabButton" customModule="MaterialKit">
<rect key="frame" x="175" y="315" width="64" height="64"/>
<animations/>
<color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</button>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
......
......@@ -79,6 +79,7 @@
96D88C731C132ACC00B91418 /* MaterialAnimation.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96D88BFF1C1328D800B91418 /* MaterialAnimation.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96D88C741C132ACC00B91418 /* MaterialBasicAnimation.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96D88C001C1328D800B91418 /* MaterialBasicAnimation.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96D88C751C132AD500B91418 /* NavigationBarView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96D88C151C1328D800B91418 /* NavigationBarView.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96F367031C20B87D00DD91F4 /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96F367021C20B87D00DD91F4 /* CameraView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -136,6 +137,7 @@
96D88C1B1C1328D800B91418 /* Roboto-Thin.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Thin.ttf"; sourceTree = "<group>"; };
96D88C1C1C1328D800B91418 /* RobotoFont.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RobotoFont.swift; sourceTree = "<group>"; };
96D88C1D1C1328D800B91418 /* SideNavigationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideNavigationViewController.swift; sourceTree = "<group>"; };
96F367021C20B87D00DD91F4 /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -233,6 +235,7 @@
96D88C491C13292700B91418 /* Capture */ = {
isa = PBXGroup;
children = (
96F367021C20B87D00DD91F4 /* CameraView.swift */,
96D88BF51C1328D800B91418 /* CaptureView.swift */,
96D88BF71C1328D800B91418 /* CapturePreviewView.swift */,
96D88BF81C1328D800B91418 /* CaptureSession.swift */,
......@@ -515,6 +518,7 @@
96D88C3F1C1328D800B91418 /* RaisedButton.swift in Sources */,
96D88C3C1C1328D800B91418 /* MaterialTransitionAnimation.swift in Sources */,
96D88C361C1328D800B91418 /* MaterialPulseView.swift in Sources */,
96F367031C20B87D00DD91F4 /* CameraView.swift in Sources */,
96D88C1E1C1328D800B91418 /* CaptureView.swift in Sources */,
96D88C2D1C1328D800B91418 /* MaterialDepth.swift in Sources */,
96D88C331C1328D800B91418 /* MaterialLabel.swift in Sources */,
......
//
// Copyright (C) 2015 CosmicMind, Inc. <http://cosmicmind.io> and other CosmicMind contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
import AVFoundation
public enum CaptureMode {
case Photo
case Video
}
public class CameraView : CaptureView, CaptureViewDelegate, CaptureSessionDelegate {
/**
:name: navigationBarView
*/
public var navigationBarView: NavigationBarView = NavigationBarView(frame: CGRectNull)
/**
:name: captureMode
*/
public private(set) lazy var captureMode: CaptureMode = .Video
/**
:name: prepareView
*/
public override func prepareView() {
super.prepareView()
prepareNavigationBarView()
prepareCaptureButton()
prepareCameraButton()
prepareVideoButton()
prepareCloseButton()
prepareSwitchCameraButton()
prepareFlashButton()
}
public func captureViewDidUpdateRecordTimer(captureView: CaptureView, duration: CMTime, time: Double, hours: Int, minutes: Int, seconds: Int) {
MaterialAnimation.animationDisabled {
self.navigationBarView.titleLabel!.text = String(format: "%02i:%02i:%02i", arguments: [hours, minutes, seconds])
}
}
public func captureViewDidStopRecordTimer(captureView: CaptureView, duration: CMTime, time: Double, hours: Int, minutes: Int, seconds: Int) {
navigationBarView.titleLabel!.hidden = true
navigationBarView.detailLabel!.hidden = true
navigationBarView.detailLabel!.textColor = MaterialColor.white
}
/**
:name: captureSessionFailedWithError
*/
public func captureSessionFailedWithError(capture: CaptureSession, error: NSError) {
print(error)
}
/**
:name: captureSessionWillSwitchCameras
*/
public func captureSessionWillSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
if .Back == position {
let img: UIImage? = UIImage(named: "ic_flash_off_white")
captureSession.flashMode = .Off
flashButton!.setImage(img, forState: .Normal)
flashButton!.setImage(img, forState: .Highlighted)
}
}
/**
:name: captureSessionDidSwitchCamerapublic s
*/
public func captureSessionDidSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
if .Back == position {
let img: UIImage? = UIImage(named: "ic_flash_auto_white")
captureSession.flashMode = .Auto
flashButton!.setImage(img, forState: .Normal)
flashButton!.setImage(img, forState: .Highlighted)
}
}
/**
:name: handleCameraButton
*/
internal func handleCameraButton(button: UIButton) {
captureButton!.backgroundColor = MaterialColor.blue.darken1.colorWithAlphaComponent(0.3)
captureMode = .Photo
}
/**
:name: handleVideoButton
*/
internal func handleVideoButton(button: UIButton) {
captureButton!.backgroundColor = MaterialColor.red.darken1.colorWithAlphaComponent(0.3)
captureMode = .Video
}
/**
:name: handleCaptureButton
*/
internal func handleCaptureButton(button: UIButton) {
if .Photo == captureMode {
captureSession.captureStillImage()
} else if .Video == captureMode {
if captureSession.isRecording {
captureSession.stopRecording()
stopTimer()
cameraButton!.hidden = false
videoButton!.hidden = false
if let v: Array<UIButton> = navigationBarView.leftButtons {
for x in v {
x.hidden = false
}
}
if let v: Array<UIButton> = navigationBarView.rightButtons {
for x in v {
x.hidden = false
}
}
navigationBarView.backgroundColor = MaterialColor.black.colorWithAlphaComponent(0.3)
} else {
previewView.layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition)
captureSession.startRecording()
startTimer()
cameraButton!.hidden = true
videoButton!.hidden = true
if let v: Array<UIButton> = navigationBarView.leftButtons {
for x in v {
x.hidden = true
}
}
if let v: Array<UIButton> = navigationBarView.rightButtons {
for x in v {
x.hidden = true
}
}
navigationBarView.backgroundColor = nil
}
}
}
/**
:name: handleSwitchCameraButton
*/
internal func handleSwitchCameraButton(button: UIButton) {
var img: UIImage?
previewView.layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition)
if .Back == captureSession.cameraPosition {
img = UIImage(named: "ic_camera_rear_white")
captureSession.switchCameras()
} else if .Front == captureSession.cameraPosition {
img = UIImage(named: "ic_camera_front_white")
captureSession.switchCameras()
}
switchCameraButton!.setImage(img, forState: .Normal)
switchCameraButton!.setImage(img, forState: .Highlighted)
}
/**
:name: handleFlashButton
*/
internal func handleFlashButton(button: UIButton) {
if .Back == captureSession.cameraPosition {
var img: UIImage?
switch captureSession.flashMode {
case .Off:
img = UIImage(named: "ic_flash_on_white")
captureSession.flashMode = .On
case .On:
img = UIImage(named: "ic_flash_auto_white")
captureSession.flashMode = .Auto
case .Auto:
img = UIImage(named: "ic_flash_off_white")
captureSession.flashMode = .Off
}
flashButton!.setImage(img, forState: .Normal)
flashButton!.setImage(img, forState: .Highlighted)
}
}
/**
:name: prepareNavigationBarView
*/
private func prepareNavigationBarView() {
navigationBarView.backgroundColor = MaterialColor.black.colorWithAlphaComponent(0.3)
navigationBarView.shadowDepth = .None
navigationBarView.statusBarStyle = .LightContent
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.hidden = true
titleLabel.textAlignment = .Center
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.regularWithSize(20)
navigationBarView.titleLabel = titleLabel
// Detail label
let detailLabel: UILabel = UILabel()
detailLabel.hidden = true
detailLabel.text = "Recording"
detailLabel.textAlignment = .Center
detailLabel.textColor = MaterialColor.white
detailLabel.font = RobotoFont.regularWithSize(12)
navigationBarView.detailLabel = detailLabel
navigationBarView.leftButtons = [closeButton!]
navigationBarView.rightButtons = [switchCameraButton!, flashButton!]
addSubview(navigationBarView)
navigationBarView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParentHorizontally(self, child: navigationBarView)
MaterialLayout.height(self, child: navigationBarView, height: 70)
}
/**
:name: prepareCaptureButton
*/
private func prepareCaptureButton() {
captureButton = FlatButton()
captureButton!.pulseColor = MaterialColor.white
captureButton!.pulseFill = true
captureButton!.backgroundColor = MaterialColor.red.darken1.colorWithAlphaComponent(0.3)
captureButton!.borderWidth = .Border2
captureButton!.borderColor = MaterialColor.white
captureButton!.shadowDepth = .None
captureButton!.addTarget(self, action: "handleCaptureButton:", forControlEvents: .TouchUpInside)
addSubview(captureButton!)
captureButton!.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomRight(self, child: captureButton!, bottom: 24, right: (bounds.width - 72) / 2)
MaterialLayout.size(self, child: captureButton!, width: 72, height: 72)
}
/**
:name: prepareCameraButton
*/
private func prepareCameraButton() {
let img4: UIImage? = UIImage(named: "ic_photo_camera_white_36pt")
cameraButton = FlatButton()
cameraButton!.pulseColor = nil
cameraButton!.setImage(img4, forState: .Normal)
cameraButton!.setImage(img4, forState: .Highlighted)
cameraButton!.addTarget(self, action: "handleCameraButton:", forControlEvents: .TouchUpInside)
addSubview(cameraButton!)
cameraButton!.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomLeft(self, child: cameraButton!, bottom: 24, left: 24)
}
/**
:name: prepareVideoButton
*/
private func prepareVideoButton() {
let img5: UIImage? = UIImage(named: "ic_videocam_white_36pt")
videoButton = FlatButton()
videoButton!.pulseColor = nil
videoButton!.setImage(img5, forState: .Normal)
videoButton!.setImage(img5, forState: .Highlighted)
videoButton!.addTarget(self, action: "handleVideoButton:", forControlEvents: .TouchUpInside)
addSubview(videoButton!)
videoButton!.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomRight(self, child: videoButton!, bottom: 24, right: 24)
}
/**
:name: prepareCloseButton
*/
private func prepareCloseButton() {
let img: UIImage? = UIImage(named: "ic_close_white")
closeButton = FlatButton()
closeButton!.pulseColor = nil
closeButton!.setImage(img, forState: .Normal)
closeButton!.setImage(img, forState: .Highlighted)
}
/**
:name: prepareSwitchCameraButton
*/
private func prepareSwitchCameraButton() {
let img: UIImage? = UIImage(named: "ic_camera_front_white")
switchCameraButton = FlatButton()
switchCameraButton!.pulseColor = nil
switchCameraButton!.setImage(img, forState: .Normal)
switchCameraButton!.setImage(img, forState: .Highlighted)
switchCameraButton!.addTarget(self, action: "handleSwitchCameraButton:", forControlEvents: .TouchUpInside)
}
/**
:name: prepareFlashButton
*/
private func prepareFlashButton() {
captureSession.flashMode = .Auto
let img: UIImage? = UIImage(named: "ic_flash_auto_white")
flashButton = FlatButton()
flashButton!.pulseColor = nil
flashButton!.setImage(img, forState: .Normal)
flashButton!.setImage(img, forState: .Highlighted)
flashButton!.addTarget(self, action: "handleFlashButton:", forControlEvents: .TouchUpInside)
}
}
......@@ -19,152 +19,26 @@
import UIKit
import AVFoundation
@objc(CapturePreviewViewDelegate)
public protocol CapturePreviewViewDelegate : MaterialDelegate {
public class CapturePreviewView : MaterialView {
/**
:name: capturePreviewViewDidTapToFocusAtPoint
:name: layerClass
*/
optional func capturePreviewViewDidTapToFocusAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
/**
:name: capturePreviewViewDidTapToExposeAtPoint
*/
optional func capturePreviewViewDidTapToExposeAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
/**
:name: capturePreviewViewDidTapToResetAtPoint
*/
optional func capturePreviewViewDidTapToResetAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint)
}
public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
/**
:name: tapToFocusGesture
*/
private var tapToFocusGesture: UITapGestureRecognizer?
/**
:name: tapToExposeGesture
*/
private var tapToExposeGesture: UITapGestureRecognizer?
/**
:name: tapToResetGesture
*/
private var tapToResetGesture: UITapGestureRecognizer?
/**
:name: previewLayer
*/
public private(set) lazy var previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer()
/**
:name: capture
*/
public private(set) lazy var captureSession: CaptureSession = CaptureSession()
/**
:name: tapToFocusEnabled
*/
public var tapToFocusEnabled: Bool {
didSet {
if tapToFocusEnabled {
tapToResetEnabled = true
prepareTapGesture(&tapToFocusGesture, numberOfTapsRequired: 1, numberOfTouchesRequired: 1, selector: "handleTapToFocusGesture:")
if let v: UITapGestureRecognizer = tapToExposeGesture {
tapToFocusGesture!.requireGestureRecognizerToFail(v)
}
} else {
removeTapGesture(&tapToFocusGesture)
}
}
}
/**
:name: tapToExposeEnabled
*/
public var tapToExposeEnabled: Bool {
didSet {
if tapToExposeEnabled {
tapToResetEnabled = true
prepareTapGesture(&tapToExposeGesture, numberOfTapsRequired: 2, numberOfTouchesRequired: 1, selector: "handleTapToExposeGesture:")
if let v: UITapGestureRecognizer = tapToFocusGesture {
v.requireGestureRecognizerToFail(tapToExposeGesture!)
}
} else {
removeTapGesture(&tapToExposeGesture)
}
}
}
/**
:name: tapToResetEnabled
*/
public var tapToResetEnabled: Bool {
didSet {
if tapToResetEnabled {
prepareTapGesture(&tapToResetGesture, numberOfTapsRequired: 2, numberOfTouchesRequired: 2, selector: "handleTapToResetGesture:")
if let v: UITapGestureRecognizer = tapToFocusGesture {
v.requireGestureRecognizerToFail(tapToResetGesture!)
}
if let v: UITapGestureRecognizer = tapToExposeGesture {
v.requireGestureRecognizerToFail(tapToResetGesture!)
}
} else {
removeTapGesture(&tapToResetGesture)
}
}
}
/**
:name: init
*/
public required init?(coder aDecoder: NSCoder) {
tapToFocusEnabled = true
tapToExposeEnabled = true
tapToResetEnabled = true
super.init(coder: aDecoder)
}
/**
:name: init
*/
public override init(frame: CGRect) {
tapToFocusEnabled = true
tapToExposeEnabled = true
tapToResetEnabled = true
super.init(frame: frame)
}
/**
:name: init
*/
public convenience init() {
self.init(frame: CGRectNull)
}
/**
:name: layoutSublayersOfLayer
*/
public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
if self.layer == layer {
layoutPreviewLayer()
}
public override class func layerClass() -> AnyClass {
return AVCaptureVideoPreviewLayer.self
}
/**
:name: captureDevicePointOfInterestForPoint
*/
public func captureDevicePointOfInterestForPoint(point: CGPoint) -> CGPoint {
return previewLayer.captureDevicePointOfInterestForPoint(point)
return (layer as! AVCaptureVideoPreviewLayer).captureDevicePointOfInterestForPoint(point)
}
/**
:name: pointForCaptureDevicePointOfInterest
*/
public func pointForCaptureDevicePointOfInterest(point: CGPoint) -> CGPoint {
return previewLayer.pointForCaptureDevicePointOfInterest(point)
return (layer as! AVCaptureVideoPreviewLayer).pointForCaptureDevicePointOfInterest(point)
}
/**
......@@ -173,79 +47,15 @@ public class CapturePreviewView : MaterialView, UIGestureRecognizerDelegate {
public override func prepareView() {
super.prepareView()
preparePreviewLayer()
tapToFocusEnabled = true
tapToExposeEnabled = true
}
/**
:name: handleTapToFocusGesture
*/
internal func handleTapToFocusGesture(recognizer: UITapGestureRecognizer) {
if tapToFocusEnabled && captureSession.cameraSupportsTapToFocus {
let point: CGPoint = recognizer.locationInView(self)
captureSession.focusAtPoint(captureDevicePointOfInterestForPoint(point))
(delegate as? CapturePreviewViewDelegate)?.capturePreviewViewDidTapToFocusAtPoint?(self, point: point)
}
}
/**
: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: handleTapToResetGesture
*/
internal func handleTapToResetGesture(recognizer: UITapGestureRecognizer) {
if tapToResetEnabled {
captureSession.resetFocusAndExposureModes()
(delegate as? CapturePreviewViewDelegate)?.capturePreviewViewDidTapToResetAtPoint?(self, point: pointForCaptureDevicePointOfInterest(CGPointMake(0.5, 0.5)))
}
}
/**
:name: preparePreviewLayer
*/
private func preparePreviewLayer() {
previewLayer.session = captureSession.session
visualLayer.addSublayer(previewLayer)
}
/**
:name: layoutPreviewLayer
*/
private func layoutPreviewLayer() {
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?, numberOfTapsRequired: Int, numberOfTouchesRequired: Int, selector: Selector) {
removeTapGesture(&gesture)
gesture = UITapGestureRecognizer(target: self, action: selector)
gesture!.delegate = self
gesture!.numberOfTapsRequired = numberOfTapsRequired
gesture!.numberOfTouchesRequired = numberOfTouchesRequired
addGestureRecognizer(gesture!)
}
/**
:name: removeTapToFocusGesture
*/
private func removeTapGesture(inout gesture: UITapGestureRecognizer?) {
if let v: UIGestureRecognizer = gesture {
removeGestureRecognizer(v)
gesture = nil
}
layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition)
layer.backgroundColor = MaterialColor.black.CGColor
layer.masksToBounds = true
(layer as! AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspectFill
}
}
\ No newline at end of file
......@@ -123,9 +123,9 @@ public protocol CaptureSessionDelegate {
@objc(CaptureSession)
public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
/**
:name: videoQueue
:name: sessionQueue
*/
private lazy var videoQueue: dispatch_queue_t = dispatch_queue_create("io.materialkit.CaptureSession", nil)
private lazy var sessionQueue: dispatch_queue_t = dispatch_queue_create("io.materialkit.CaptureSession", DISPATCH_QUEUE_SERIAL)
/**
:name: activeVideoInput
......@@ -182,15 +182,6 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
}
/**
:name: init
*/
public override init() {
sessionPreset = .PresetHigh
super.init()
prepareSession()
}
/**
:name: inactiveCamera
*/
public var inactiveCamera: AVCaptureDevice? {
......@@ -368,11 +359,20 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
public weak var delegate: CaptureSessionDelegate?
/**
:name: init
*/
public override init() {
sessionPreset = .PresetHigh
super.init()
prepareSession()
}
/**
:name: startSession
*/
public func startSession() {
if !isRunning {
dispatch_async(videoQueue) {
dispatch_async(sessionQueue) {
self.session.startRunning()
}
}
......@@ -383,7 +383,7 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
*/
public func stopSession() {
if isRunning {
dispatch_async(videoQueue) {
dispatch_async(sessionQueue) {
self.session.stopRunning()
}
}
......@@ -542,14 +542,16 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
:name: captureStillImage
*/
public func captureStillImage() {
let connection: AVCaptureConnection = imageOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = currentVideoOrientation
imageOutput.captureStillImageAsynchronouslyFromConnection(connection) { (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in
if nil == error {
let data: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
self.delegate?.captureStillImageAsynchronously?(self, image: UIImage(data: data)!)
} else {
self.delegate?.captureStillImageAsynchronouslyFailedWithError?(self, error: error!)
dispatch_async(sessionQueue) {
let connection: AVCaptureConnection = self.imageOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = self.currentVideoOrientation
self.imageOutput.captureStillImageAsynchronouslyFromConnection(connection) { (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in
if nil == error {
let data: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
self.delegate?.captureStillImageAsynchronously?(self, image: UIImage(data: data)!)
} else {
self.delegate?.captureStillImageAsynchronouslyFailedWithError?(self, error: error!)
}
}
}
}
......@@ -559,24 +561,26 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
*/
public func startRecording() {
if !self.isRecording {
let connection: AVCaptureConnection = self.movieOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = self.currentVideoOrientation
connection.preferredVideoStabilizationMode = .Auto
let device: AVCaptureDevice = self.activeCamera!
if device.smoothAutoFocusSupported {
do {
try device.lockForConfiguration()
device.smoothAutoFocusEnabled = true
device.unlockForConfiguration()
} catch let e as NSError {
self.delegate?.captureSessionFailedWithError?(self, error: e)
dispatch_async(sessionQueue) {
let connection: AVCaptureConnection = self.movieOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = self.currentVideoOrientation
connection.preferredVideoStabilizationMode = .Auto
let device: AVCaptureDevice = self.activeCamera!
if device.smoothAutoFocusSupported {
do {
try device.lockForConfiguration()
device.smoothAutoFocusEnabled = true
device.unlockForConfiguration()
} catch let e as NSError {
self.delegate?.captureSessionFailedWithError?(self, error: e)
}
}
self.movieOutputURL = self.uniqueURL()
if let v: NSURL = self.movieOutputURL {
self.movieOutput.startRecordingToOutputFileURL(v, recordingDelegate: self)
}
}
self.movieOutputURL = self.uniqueURL()
if let v: NSURL = self.movieOutputURL {
self.movieOutput.startRecordingToOutputFileURL(v, recordingDelegate: self)
}
}
}
......
......@@ -17,154 +17,300 @@
//
import UIKit
import AVFoundation
public class CaptureView : MaterialView, CapturePreviewViewDelegate {
@objc(CaptureViewDelegate)
public protocol CaptureViewDelegate : MaterialDelegate {
/**
:name: captureViewDidStartRecordTimer
*/
optional func captureViewDidStartRecordTimer(captureView: CaptureView)
/**
:name: captureViewDidUpdateRecordTimer
*/
optional func captureViewDidUpdateRecordTimer(captureView: CaptureView, duration: CMTime, time: Double, hours: Int, minutes: Int, seconds: Int)
/**
:name: captureViewDidStopRecordTimer
*/
optional func captureViewDidStopRecordTimer(captureView: CaptureView, duration: CMTime, time: Double, hours: Int, minutes: Int, seconds: Int)
/**
:name: captureViewDidTapToFocusAtPoint
*/
optional func captureViewDidTapToFocusAtPoint(captureView: CaptureView, point: CGPoint)
/**
:name: captureViewDidTapToExposeAtPoint
*/
optional func captureViewDidTapToExposeAtPoint(captureView: CaptureView, point: CGPoint)
/**
:name: captureViewDidTapToResetAtPoint
*/
optional func captureViewDidTapToResetAtPoint(captureView: CaptureView, point: CGPoint)
}
public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
/**
:name: timer
*/
private var timer: NSTimer?
/**
:name: tapToFocusGesture
*/
private var tapToFocusGesture: UITapGestureRecognizer?
/**
:name: tapToExposeGesture
*/
private var tapToExposeGesture: UITapGestureRecognizer?
/**
:name: tapToResetGesture
*/
private var tapToResetGesture: UITapGestureRecognizer?
/**
:name: tapToResetEnabled
*/
private var tapToResetEnabled: Bool = false {
didSet {
if tapToResetEnabled {
prepareTapGesture(&tapToResetGesture, numberOfTapsRequired: 2, numberOfTouchesRequired: 2, selector: "handleTapToResetGesture:")
if let v: UITapGestureRecognizer = tapToFocusGesture {
v.requireGestureRecognizerToFail(tapToResetGesture!)
}
if let v: UITapGestureRecognizer = tapToExposeGesture {
v.requireGestureRecognizerToFail(tapToResetGesture!)
}
} else {
removeTapGesture(&tapToResetGesture)
}
}
}
/**
:name: previewView
*/
public private(set) lazy var previewView: CapturePreviewView = CapturePreviewView()
/**
:name: focusLayer
:name: capture
*/
public private(set) lazy var captureSession: CaptureSession = CaptureSession()
/**
:name: focusView
*/
public var focusView: MaterialView? {
didSet {
if nil == focusView {
removeTapGesture(&tapToFocusGesture)
} else {
tapToResetEnabled = true
prepareFocusView()
prepareTapGesture(&tapToFocusGesture, numberOfTapsRequired: 1, numberOfTouchesRequired: 1, selector: "handleTapToFocusGesture:")
if let v: UITapGestureRecognizer = tapToExposeGesture {
tapToFocusGesture!.requireGestureRecognizerToFail(v)
}
}
}
}
/**
:name: exposureView
*/
public private(set) lazy var focusLayer: MaterialLayer = MaterialLayer()
public var exposureView: MaterialView? {
didSet {
if nil == exposureView {
removeTapGesture(&tapToExposeGesture)
} else {
tapToResetEnabled = true
prepareExposureView()
prepareTapGesture(&tapToExposeGesture, numberOfTapsRequired: 2, numberOfTouchesRequired: 1, selector: "handleTapToExposeGesture:")
if let v: UITapGestureRecognizer = tapToFocusGesture {
v.requireGestureRecognizerToFail(tapToExposeGesture!)
}
}
}
}
/**
:name: exposureLayer
:name: closeButton
*/
public private(set) lazy var exposureLayer: MaterialLayer = MaterialLayer()
public var closeButton: MaterialButton?
/**
:name: cameraButton
*/
public var cameraButton: MaterialButton?
/**
:name: captureButton
*/
public var captureButton: UIButton?
public var captureButton: MaterialButton?
/**
:name: switchCamerasButton
:name: videoButton
*/
public var switchCamerasButton: UIButton?
public var videoButton: MaterialButton?
/**
:name: switchCameraButton
*/
public var switchCameraButton: MaterialButton?
/**
:name: flashButton
*/
public var flashButton: UIButton?
public var flashButton: MaterialButton?
/**
:name: captureSession
:name: prepareView
*/
public var captureSession: CaptureSession {
return previewView.captureSession
public override func prepareView() {
super.prepareView()
prepareCapturePreviewView()
}
/**
:name: init
:name: startTimer
*/
public convenience init() {
self.init(frame: CGRectNull)
internal func startTimer() {
timer?.invalidate()
timer = NSTimer(timeInterval: 0.5, target: self, selector: "updateTimer", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes)
(delegate as? CaptureViewDelegate)?.captureViewDidStartRecordTimer?(self)
}
/**
:name: layoutSublayersOfLayer
:name: updateTimer
*/
public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
if self.layer == layer {
}
internal func updateTimer() {
let duration: CMTime = captureSession.recordedDuration
let time: Double = CMTimeGetSeconds(duration)
let hours: Int = Int(time / 3600)
let minutes: Int = Int((time / 60) % 60)
let seconds: Int = Int(time % 60)
(delegate as? CaptureViewDelegate)?.captureViewDidUpdateRecordTimer?(self, duration: duration, time: time, hours: hours, minutes: minutes, seconds: seconds)
}
/**
:name: reloadView
:name: stopTimer
*/
public func reloadView() {
previewView.removeFromSuperview()
addSubview(previewView)
MaterialLayout.alignToParent(self, child: previewView)
internal func stopTimer() {
let duration: CMTime = captureSession.recordedDuration
let time: Double = CMTimeGetSeconds(duration)
let hours: Int = Int(time / 3600)
let minutes: Int = Int((time / 60) % 60)
let seconds: Int = Int(time % 60)
timer?.invalidate()
timer = nil
(delegate as? CaptureViewDelegate)?.captureViewDidStopRecordTimer?(self, duration: duration, time: time, hours: hours, minutes: minutes, seconds: seconds)
}
/**
:name: capturePreviewViewDidTapToFocusAtPoint
:name: handleTapToFocusGesture
*/
public func capturePreviewViewDidTapToFocusAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint) {
MaterialAnimation.animationDisabled {
self.focusLayer.position = point
self.focusLayer.hidden = false
}
MaterialAnimation.animateWithDuration(0.25, animations: {
self.focusLayer.transform = CATransform3DMakeScale(0, 0, 1)
}) {
MaterialAnimation.animationDisabled {
self.focusLayer.hidden = true
self.focusLayer.transform = CATransform3DIdentity
internal func handleTapToFocusGesture(recognizer: UITapGestureRecognizer) {
if let v: MaterialView = focusView {
if captureSession.cameraSupportsTapToFocus {
let point: CGPoint = recognizer.locationInView(self)
captureSession.focusAtPoint(previewView.captureDevicePointOfInterestForPoint(point))
MaterialAnimation.animationDisabled {
v.layer.transform = CATransform3DIdentity
v.position = point
v.hidden = false
}
MaterialAnimation.animateWithDuration(0.25, animations: {
v.layer.transform = CATransform3DMakeScale(0.5, 0.5, 1)
}) {
MaterialAnimation.delay(0.4) {
MaterialAnimation.animationDisabled {
v.hidden = true
}
}
}
(delegate as? CaptureViewDelegate)?.captureViewDidTapToFocusAtPoint?(self, point: point)
}
}
}
/**
:name: capturePreviewViewDidTapToExposeAtPoint
:name: handleTapToExposeGesture
*/
public func capturePreviewViewDidTapToExposeAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint) {
MaterialAnimation.animationDisabled {
self.exposureLayer.position = point
self.exposureLayer.hidden = false
internal func handleTapToExposeGesture(recognizer: UITapGestureRecognizer) {
if nil != exposureView && captureSession.cameraSupportsTapToExpose {
let point: CGPoint = recognizer.locationInView(self)
captureSession.exposeAtPoint(previewView.captureDevicePointOfInterestForPoint(point))
(delegate as? CaptureViewDelegate)?.captureViewDidTapToExposeAtPoint?(self, point: point)
}
MaterialAnimation.animateWithDuration(0.25, animations: {
self.exposureLayer.transform = CATransform3DMakeScale(0, 0, 1)
}) {
MaterialAnimation.animationDisabled {
self.exposureLayer.hidden = true
self.exposureLayer.transform = CATransform3DIdentity
}
}
/**
:name: handleTapToResetGesture
*/
internal func handleTapToResetGesture(recognizer: UITapGestureRecognizer) {
if tapToResetEnabled {
captureSession.resetFocusAndExposureModes()
let point: CGPoint = previewView.pointForCaptureDevicePointOfInterest(CGPointMake(0.5, 0.5))
(delegate as? CaptureViewDelegate)?.captureViewDidTapToResetAtPoint?(self, point: point)
}
}
/**
:name: capturePreviewViewDidTapToResetAtPoint
:name: prepareTapGesture
*/
public func capturePreviewViewDidTapToResetAtPoint(capturePreviewView: CapturePreviewView, point: CGPoint) {
capturePreviewViewDidTapToFocusAtPoint(capturePreviewView, point: point)
capturePreviewViewDidTapToExposeAtPoint(capturePreviewView, point: point)
private func prepareTapGesture(inout gesture: UITapGestureRecognizer?, numberOfTapsRequired: Int, numberOfTouchesRequired: Int, selector: Selector) {
removeTapGesture(&gesture)
gesture = UITapGestureRecognizer(target: self, action: selector)
gesture!.delegate = self
gesture!.numberOfTapsRequired = numberOfTapsRequired
gesture!.numberOfTouchesRequired = numberOfTouchesRequired
addGestureRecognizer(gesture!)
}
/**
:name: prepareView
:name: removeTapToFocusGesture
*/
public override func prepareView() {
super.prepareView()
preparePreviewView()
prepareFocusLayer()
prepareExposureLayer()
reloadView()
private func removeTapGesture(inout gesture: UITapGestureRecognizer?) {
if let v: UIGestureRecognizer = gesture {
removeGestureRecognizer(v)
gesture = nil
}
}
/**
:name: preparePreviewView
:name: prepareCapturePreviewView
*/
private func preparePreviewView() {
private func prepareCapturePreviewView() {
(previewView.layer as! AVCaptureVideoPreviewLayer).session = captureSession.session
captureSession.startSession()
addSubview(previewView)
previewView.translatesAutoresizingMaskIntoConstraints = false
previewView.delegate = self
previewView.captureSession.startSession()
MaterialLayout.alignToParent(self, child: previewView)
}
/**
:name: prepareFocusLayer
:name: prepareFocusView
*/
private func prepareFocusLayer() {
focusLayer.hidden = true
focusLayer.backgroundColor = MaterialColor.blue.base.colorWithAlphaComponent(0.25).CGColor
focusLayer.bounds = CGRectMake(0, 0, 150, 150)
focusLayer.cornerRadius = 75
previewView.layer.addSublayer(focusLayer)
private func prepareFocusView() {
if let v: MaterialView = focusView {
addSubview(v)
v.hidden = true
}
}
/**
:name: prepareExposureLayer
:name: prepareExposureView
*/
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)
private func prepareExposureView() {
if let v: MaterialView = exposureView {
addSubview(v)
v.hidden = true
}
}
}
\ No newline at end of file
......@@ -49,8 +49,45 @@ public func MaterialAnimationFillModeToValue(mode: MaterialAnimationFillMode) ->
}
}
public typealias MaterialAnimationDelayCancelBlock = (cancel : Bool) -> Void
public struct MaterialAnimation {
/**
:name: delay
*/
public static func delay(time: NSTimeInterval, completion: ()-> Void) -> MaterialAnimationDelayCancelBlock? {
func dispatch_later(completion: ()-> Void) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), completion)
}
var cancelable: MaterialAnimationDelayCancelBlock?
let delayed: MaterialAnimationDelayCancelBlock = { cancel in
if !cancel {
dispatch_async(dispatch_get_main_queue(), completion)
}
cancelable = nil
}
cancelable = delayed
dispatch_later {
cancelable?(cancel: false)
}
return cancelable;
}
/**
:name: delayCancel
*/
public static func delayCancel(completion: MaterialAnimationDelayCancelBlock?) {
completion?(cancel: true)
}
/**
:name: animationDisabled
*/
public static func animationDisabled(animations: (() -> Void)) {
......@@ -81,4 +118,13 @@ public struct MaterialAnimation {
group.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
return group
}
/**
:name: animateWithDelay
*/
public static func animateWithDelay(delay d: CFTimeInterval, duration: CFTimeInterval, animations: (() -> Void), options: UIViewAnimationOptions? = nil, completion: (() -> Void)? = nil) {
delay(d) {
animateWithDuration(duration, animations: animations, options: options, completion: completion)
}
}
}
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