diff --git a/camera.xcodeproj/project.pbxproj b/camera.xcodeproj/project.pbxproj index 92c29c5..500be77 100644 --- a/camera.xcodeproj/project.pbxproj +++ b/camera.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 454C1F4C19E82E2500C81915 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 454C1F4A19E82E2500C81915 /* Main.storyboard */; }; 454C1F4E19E82E2500C81915 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 454C1F4D19E82E2500C81915 /* Images.xcassets */; }; 454C1F5119E82E2500C81915 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 454C1F4F19E82E2500C81915 /* LaunchScreen.xib */; }; - 454C1F6719E8316A00C81915 /* CameraManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 454C1F6619E8316A00C81915 /* CameraManager.swift */; }; 45A23C181A656BDC00FB48F3 /* ImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A23C171A656BDC00FB48F3 /* ImageViewController.swift */; }; D71DE8861AD677A7001E62F1 /* CameraManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D71DE8851AD677A7001E62F1 /* CameraManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; D71DE8981AD677A8001E62F1 /* CameraManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D71DE8811AD677A7001E62F1 /* CameraManager.framework */; }; @@ -52,7 +51,7 @@ 454C1F4B19E82E2500C81915 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 454C1F4D19E82E2500C81915 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 454C1F5019E82E2500C81915 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 454C1F6619E8316A00C81915 /* CameraManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraManager.swift; sourceTree = ""; }; + 454C1F6619E8316A00C81915 /* CameraManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CameraManager.swift; path = ../camera/CameraManager.swift; sourceTree = ""; }; 45A23C171A656BDC00FB48F3 /* ImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewController.swift; sourceTree = ""; }; D71DE8811AD677A7001E62F1 /* CameraManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CameraManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D71DE8841AD677A7001E62F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -101,7 +100,6 @@ children = ( 454C1F4619E82E2500C81915 /* AppDelegate.swift */, 45A23C191A656BE600FB48F3 /* Example app view controllers */, - 454C1F6619E8316A00C81915 /* CameraManager.swift */, 454C1F4A19E82E2500C81915 /* Main.storyboard */, 454C1F4D19E82E2500C81915 /* Images.xcassets */, 454C1F4F19E82E2500C81915 /* LaunchScreen.xib */, @@ -131,6 +129,7 @@ isa = PBXGroup; children = ( D71DE8851AD677A7001E62F1 /* CameraManager.h */, + 454C1F6619E8316A00C81915 /* CameraManager.swift */, D71DE8831AD677A7001E62F1 /* Supporting Files */, ); path = CameraManager; @@ -258,7 +257,6 @@ buildActionMask = 2147483647; files = ( 454C1F4919E82E2500C81915 /* ViewController.swift in Sources */, - 454C1F6719E8316A00C81915 /* CameraManager.swift in Sources */, 45A23C181A656BDC00FB48F3 /* ImageViewController.swift in Sources */, 454C1F4719E82E2500C81915 /* AppDelegate.swift in Sources */, ); diff --git a/camera/CameraManager.swift b/camera/CameraManager.swift index 0b3e4ff..6d82831 100644 --- a/camera/CameraManager.swift +++ b/camera/CameraManager.swift @@ -153,7 +153,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { // MARK: - Private properties - private weak var embedingView: UIView? + private weak var embeddingView: UIView? private var videoCompletition: ((videoURL: NSURL?, error: NSError?) -> Void)? private var sessionQueue: dispatch_queue_t = dispatch_queue_create("CameraSessionQueue", DISPATCH_QUEUE_SERIAL) @@ -179,6 +179,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { private var cameraIsSetup = false private var cameraIsObservingDeviceOrientation = false + private var zoomScale = CGFloat(1.0) private var tempFilePath: NSURL = { let tempPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("tempMovie").URLByAppendingPathExtension("mp4").absoluteString @@ -188,7 +189,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { } catch { } } return NSURL(string: tempPath)! - }() + }() // MARK: - CameraManager @@ -210,7 +211,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { } public func addPreviewLayerToView(view: UIView, newCameraOutputMode: CameraOutputMode, completition: (Void -> Void)?) -> CameraState { if _canLoadCamera() { - if let _ = embedingView { + if let _ = embeddingView { if let validPreviewLayer = previewLayer { validPreviewLayer.removeFromSuperlayer() } @@ -280,8 +281,8 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { stopAndRemoveCaptureSession() } _setupCamera({Void -> Void in - if let validEmbedingView = self.embedingView { - self._addPreviewLayerToView(validEmbedingView) + if let validEmbeddingView = self.embeddingView { + self._addPreviewLayerToView(validEmbeddingView) } self._startFollowingDeviceOrientation() }) @@ -438,6 +439,43 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { // MARK: - CameraManager() + private func attachZoom(view: UIView) { + let pinch = UIPinchGestureRecognizer(target: self, action: "_zoom:") + view.addGestureRecognizer(pinch) + } + + @objc + private func _zoom(recognizer: UIPinchGestureRecognizer) { + guard let view = embeddingView, + previewLayer = previewLayer + else { return } + + var allTouchesOnPreviewLayer = true + let numTouch = recognizer.numberOfTouches() + + for var i = 0; i < numTouch; i++ { + let location = recognizer.locationOfTouch(i, inView: view) + let convertedTouch = previewLayer.convertPoint(location, fromLayer: previewLayer.superlayer) + if !previewLayer.containsPoint(convertedTouch) { + allTouchesOnPreviewLayer = false + break + } + } + if allTouchesOnPreviewLayer { + do { + let captureDevice = AVCaptureDevice.devices().first as? AVCaptureDevice + try captureDevice?.lockForConfiguration() + if recognizer.scale >= 1.0 { + captureDevice?.videoZoomFactor = recognizer.scale + zoomScale = recognizer.scale + } + captureDevice?.unlockForConfiguration() + } catch { + print("Error locking configuration") + } + } + } + private func _updateTorch(flashMode: CameraFlashMode) { captureSession?.beginConfiguration() let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) @@ -522,8 +560,8 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { } } dispatch_async(dispatch_get_main_queue(), { () -> Void in - if let validEmbedingView = self.embedingView { - validPreviewLayer.frame = validEmbedingView.bounds + if let validEmbeddingView = self.embeddingView { + validPreviewLayer.frame = validEmbeddingView.bounds } }) } @@ -584,7 +622,8 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { } private func _addPreviewLayerToView(view: UIView) { - embedingView = view + embeddingView = view + attachZoom(view) dispatch_async(dispatch_get_main_queue(), { () -> Void in guard let _ = self.previewLayer else { return diff --git a/camera/ViewController.swift b/camera/ViewController.swift index fc739b0..ce5f454 100644 --- a/camera/ViewController.swift +++ b/camera/ViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import CameraManager class ViewController: UIViewController {