diff --git a/Demo/ImagePickerDemo/ImagePickerDemo.xcodeproj/project.pbxproj b/Demo/ImagePickerDemo/ImagePickerDemo.xcodeproj/project.pbxproj index 12b028e7..6115018b 100644 --- a/Demo/ImagePickerDemo/ImagePickerDemo.xcodeproj/project.pbxproj +++ b/Demo/ImagePickerDemo/ImagePickerDemo.xcodeproj/project.pbxproj @@ -180,7 +180,8 @@ 29D699D11B70ABFC0021FA73 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0640; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "Ramon Gilabert Llop"; TargetAttributes = { 29D699D81B70ABFC0021FA73 = { @@ -340,6 +341,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; diff --git a/Demo/ImagePickerDemo/ImagePickerDemo/Info.plist b/Demo/ImagePickerDemo/ImagePickerDemo/Info.plist index 2b940009..1fb982dd 100644 --- a/Demo/ImagePickerDemo/ImagePickerDemo/Info.plist +++ b/Demo/ImagePickerDemo/ImagePickerDemo/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - Hyper.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Demo/ImagePickerDemo/ImagePickerDemoTests/Info.plist b/Demo/ImagePickerDemo/ImagePickerDemoTests/Info.plist index d65b095b..ba72822e 100644 --- a/Demo/ImagePickerDemo/ImagePickerDemoTests/Info.plist +++ b/Demo/ImagePickerDemo/ImagePickerDemoTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - Hyper.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Demo/ImagePickerDemo/Podfile.lock b/Demo/ImagePickerDemo/Podfile.lock index c77782d6..af241783 100644 --- a/Demo/ImagePickerDemo/Podfile.lock +++ b/Demo/ImagePickerDemo/Podfile.lock @@ -6,9 +6,9 @@ DEPENDENCIES: EXTERNAL SOURCES: ImagePicker: - :path: ../../ + :path: "../../" SPEC CHECKSUMS: ImagePicker: 32becfa25b8e9179e60c45411b577340d35e3e32 -COCOAPODS: 0.37.2 +COCOAPODS: 0.38.2 diff --git a/Source/BottomView/BottomContainerView.swift b/Source/BottomView/BottomContainerView.swift index 350069d3..426031f4 100644 --- a/Source/BottomView/BottomContainerView.swift +++ b/Source/BottomView/BottomContainerView.swift @@ -70,7 +70,7 @@ class BottomContainerView: UIView { for view in [borderPickerButton, pickerButton, doneButton, stackView, topSeparator] { addSubview(view) - view.setTranslatesAutoresizingMaskIntoConstraints(false) + view.translatesAutoresizingMaskIntoConstraints = false } backgroundColor = configuration.backgroundColor @@ -79,7 +79,7 @@ class BottomContainerView: UIView { setupConstraints() } - required init(coder aDecoder: NSCoder) { + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/Source/BottomView/ButtonPicker.swift b/Source/BottomView/ButtonPicker.swift index 60048274..73bf44ea 100644 --- a/Source/BottomView/ButtonPicker.swift +++ b/Source/BottomView/ButtonPicker.swift @@ -15,7 +15,7 @@ class ButtonPicker: UIButton { lazy var numberLabel: UILabel = { [unowned self] in let label = UILabel() - label.setTranslatesAutoresizingMaskIntoConstraints(false) + label.translatesAutoresizingMaskIntoConstraints = false label.font = self.configuration.numberLabelFont return label @@ -33,7 +33,7 @@ class ButtonPicker: UIButton { override init(frame: CGRect) { super.init(frame: frame) - [numberLabel].map { self.addSubview($0) } + addSubview(numberLabel) subscribe() setupButton() @@ -61,7 +61,7 @@ class ButtonPicker: UIButton { object: nil) } - required init(coder aDecoder: NSCoder) { + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -79,9 +79,9 @@ class ButtonPicker: UIButton { func setupConstraints() { let attributes: [NSLayoutAttribute] = [.CenterX, .CenterY] - attributes.map { - self.addConstraint(NSLayoutConstraint(item: self.numberLabel, attribute: $0, - relatedBy: .Equal, toItem: self, attribute: $0, + for attribute in attributes { + addConstraint(NSLayoutConstraint(item: numberLabel, attribute: attribute, + relatedBy: .Equal, toItem: self, attribute: attribute, multiplier: 1, constant: 0)) } } diff --git a/Source/BottomView/ImageStack.swift b/Source/BottomView/ImageStack.swift index 3c7134f2..e715b36d 100644 --- a/Source/BottomView/ImageStack.swift +++ b/Source/BottomView/ImageStack.swift @@ -27,6 +27,6 @@ public class ImageStack { } public func containsImage(image: UIImage) -> Bool { - return contains(images, image) + return images.contains(image) } } diff --git a/Source/BottomView/StackView.swift b/Source/BottomView/StackView.swift index 7289c9fd..08f53203 100644 --- a/Source/BottomView/StackView.swift +++ b/Source/BottomView/StackView.swift @@ -31,14 +31,18 @@ class ImageStackView: UIView { override init(frame: CGRect) { super.init(frame: frame) - + subscribe() - views.map { self.addSubview($0) } + + for view in views { + addSubview(view) + } + views[0].alpha = 1 layoutSubviews() } - required init(coder aDecoder: NSCoder) { + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -74,10 +78,10 @@ class ImageStackView: UIView { let offset = -step * CGFloat(views.count) var origin = CGPoint(x: offset, y: offset) - for (i, view) in enumerate(views) { + for (_, view) in views.enumerate() { origin.x += step origin.y += step - var frame = CGRect(origin: origin, size: viewSize) + let frame = CGRect(origin: origin, size: viewSize) view.frame = frame } } @@ -116,9 +120,9 @@ extension ImageStackView { return } - let photos = suffix(images, 4) + let photos = Array(images.suffix(4)) - for (index, view) in enumerate(views) { + for (index, view) in views.enumerate() { if index <= photos.count - 1 { view.image = photos[index] view.alpha = 1 @@ -132,7 +136,7 @@ extension ImageStackView { private func animateImageView(imageView: UIImageView) { imageView.transform = CGAffineTransformMakeScale(0, 0) - UIView.animateWithDuration(0.3, animations: { [unowned self] in + UIView.animateWithDuration(0.3, animations: { imageView.transform = CGAffineTransformMakeScale(1.05, 1.05) }, completion: { _ in UIView.animateWithDuration(0.2, animations: { _ in @@ -141,4 +145,3 @@ extension ImageStackView { }) } } - diff --git a/Source/CameraView/CameraView.swift b/Source/CameraView/CameraView.swift index 4c91494b..9ed2d682 100644 --- a/Source/CameraView/CameraView.swift +++ b/Source/CameraView/CameraView.swift @@ -26,7 +26,7 @@ class CameraView: UIViewController { lazy var focusImageView: UIImageView = { [unowned self] in let imageView = UIImageView() imageView.image = self.getImage("focusIcon") - imageView.backgroundColor = UIColor.clearColor() + imageView.backgroundColor = .clearColor() imageView.frame = CGRectMake(0, 0, 110, 110) imageView.alpha = 0 self.view.addSubview(imageView) @@ -34,6 +34,15 @@ class CameraView: UIViewController { return imageView }() + lazy var capturedImageView: UIView = { [unowned self] in + let view = UIView() + view.backgroundColor = .blackColor() + view.alpha = 0 + self.view.addSubview(view) + + return view + }() + lazy var containerView: UIView = { let view = UIView() view.alpha = 0 @@ -62,7 +71,7 @@ class CameraView: UIViewController { // MARK: - Initialize camera func initializeCamera() { - captureSession.sessionPreset = AVCaptureSessionPreset640x480 + captureSession.sessionPreset = AVCaptureSessionPreset1280x720 capturedDevices = NSMutableArray() let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) @@ -84,6 +93,8 @@ class CameraView: UIViewController { } } + captureDevice = capturedDevices?.firstObject as? AVCaptureDevice + if captureDevice != nil { beginSession() } @@ -111,16 +122,21 @@ class CameraView: UIViewController { delegate?.handleFlashButton(captureDevice?.position == .Front) - var error: NSError? = nil - UIView.animateWithDuration(0.3, animations: { [unowned self] in self.containerView.alpha = 1 }, completion: { finished in self.captureSession.beginConfiguration() self.captureSession.removeInput(currentDeviceInput) - self.captureSession.addInput(AVCaptureDeviceInput(device: self.captureDevice, error: &error)) + + if self.captureDevice!.supportsAVCaptureSessionPreset(AVCaptureSessionPreset1280x720) { + self.captureSession.sessionPreset = AVCaptureSessionPreset1280x720 + } else { + self.captureSession.sessionPreset = AVCaptureSessionPreset640x480 + } + + try! self.captureSession.addInput(AVCaptureDeviceInput(device: self.captureDevice)) self.captureSession.commitConfiguration() - UIView.animateWithDuration(1.3, animations: { [unowned self] in + UIView.animateWithDuration(0.7, animations: { [unowned self] in self.containerView.alpha = 0 }) }) @@ -129,7 +145,10 @@ class CameraView: UIViewController { func flashCamera(title: String) { if (captureDevice?.hasFlash != nil) { - captureDevice?.lockForConfiguration(nil) + do { + try captureDevice?.lockForConfiguration() + } catch _ { + } switch title { case "ON": captureDevice?.flashMode = .On @@ -143,22 +162,57 @@ class CameraView: UIViewController { } func takePicture() { + capturedImageView.frame = view.bounds + + UIView.animateWithDuration(0.1, animations: { + self.capturedImageView.alpha = 1 + }, completion: { _ in + UIView.animateWithDuration(0.1, animations: { + self.capturedImageView.alpha = 0 + }) + }) + let queue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL) let videoOrientation = previewLayer?.connection.videoOrientation + stillImageOutput?.connectionWithMediaType(AVMediaTypeVideo).videoOrientation = videoOrientation! dispatch_async(queue, { [unowned self] in self.stillImageOutput!.captureStillImageAsynchronouslyFromConnection(self.stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo), completionHandler: { (buffer, error) -> Void in let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer) - let image = UIImage(data: imageData) - self.delegate?.imageToLibrary(image!) - let orientation = ALAssetOrientation(rawValue: image!.imageOrientation.rawValue) + let image = self.cropImage(UIImage(data: imageData)!) + let orientation = self.pictureOrientation() let assetsLibrary = ALAssetsLibrary() - assetsLibrary.writeImageToSavedPhotosAlbum(image!.CGImage, orientation: orientation!, completionBlock: nil) + assetsLibrary.writeImageToSavedPhotosAlbum(image.CGImage, orientation: orientation, completionBlock: nil) + + let rotatedImage = UIImage(CGImage: image.CGImage!, + scale: 1.0, + orientation: UIImageOrientation(rawValue: orientation.rawValue)!) + self.delegate?.imageToLibrary(rotatedImage) }) }) } + func cropImage(image: UIImage) -> UIImage { + let imageReference = CGImageCreateWithImageInRect(image.CGImage, CGRect(x: 0, y: 0, width: image.size.height - 200, height: image.size.width)) + let normalizedImage = UIImage(CGImage: imageReference!, scale: 1, orientation: .Right) + + return normalizedImage + } + + func pictureOrientation() -> ALAssetOrientation { + switch UIDevice.currentDevice().orientation { + case .LandscapeLeft: + return .Up + case .LandscapeRight: + return .Down + case .PortraitUpsideDown: + return .Left + default: + return .Right + } + } + // MARK: - Timer methods func timerDidFire() { @@ -173,24 +227,25 @@ class CameraView: UIViewController { func focusTo(point: CGPoint) { if let device = captureDevice { - if device.lockForConfiguration(nil) - && device.isFocusModeSupported(AVCaptureFocusMode.Locked) { - device.focusPointOfInterest = CGPointMake(point.x / UIScreen.mainScreen().bounds.width, point.y / UIScreen.mainScreen().bounds.height) - device.unlockForConfiguration() - focusImageView.center = point - UIView.animateWithDuration(0.5, animations: { [unowned self] in - self.focusImageView.alpha = 1 - self.focusImageView.transform = CGAffineTransformMakeScale(0.6, 0.6) - }, completion: { _ in - self.animationTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, - selector: "timerDidFire", userInfo: nil, repeats: false) - }) + + do { try device.lockForConfiguration() } catch { } + if device.isFocusModeSupported(AVCaptureFocusMode.Locked) { + device.focusPointOfInterest = CGPointMake(point.x / UIScreen.mainScreen().bounds.width, point.y / UIScreen.mainScreen().bounds.height) + device.unlockForConfiguration() + focusImageView.center = point + UIView.animateWithDuration(0.5, animations: { [unowned self] in + self.focusImageView.alpha = 1 + self.focusImageView.transform = CGAffineTransformMakeScale(0.6, 0.6) + }, completion: { _ in + self.animationTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, + selector: "timerDidFire", userInfo: nil, repeats: false) + }) } } } - override func touchesBegan(touches: Set, withEvent event: UIEvent) { - let anyTouch = touches.first as! UITouch + override func touchesBegan(touches: Set, withEvent event: UIEvent?) { + let anyTouch = touches.first! let touchX = anyTouch.locationInView(view).x let touchY = anyTouch.locationInView(view).y focusImageView.transform = CGAffineTransformIdentity @@ -200,26 +255,31 @@ class CameraView: UIViewController { func configureDevice() { if let device = captureDevice { - device.lockForConfiguration(nil) + do { + try device.lockForConfiguration() + } catch _ { + } device.unlockForConfiguration() } } func beginSession() { configureDevice() - var error: NSError? = nil if captureSession.inputs.count == 0 { - captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error)) - - if error != nil { - println("error: \(error?.localizedDescription)") + let captureDeviceInput: AVCaptureDeviceInput? + do { try + captureDeviceInput = AVCaptureDeviceInput(device: self.captureDevice) + captureSession.addInput(captureDeviceInput) + } catch { + print("failed to capture device") } + previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer?.autoreverses = true previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill view.clipsToBounds = true - view.layer.addSublayer(previewLayer) + view.layer.addSublayer(previewLayer!) previewLayer?.frame = view.layer.frame captureSession.startRunning() delegate?.handleFlashButton(captureDevice?.position == .Front) diff --git a/Source/Extensions/ConstraintsSetup.swift b/Source/Extensions/ConstraintsSetup.swift index 76b2f2be..c0681b98 100644 --- a/Source/Extensions/ConstraintsSetup.swift +++ b/Source/Extensions/ConstraintsSetup.swift @@ -77,11 +77,19 @@ extension TopView { addConstraint(NSLayoutConstraint(item: rotateCamera, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, - multiplier: 1, constant: -Dimensions.rightOffset)) + multiplier: 1, constant: Dimensions.rightOffset)) addConstraint(NSLayoutConstraint(item: rotateCamera, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0)) + + addConstraint(NSLayoutConstraint(item: rotateCamera, attribute: .Width, + relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, + multiplier: 1, constant: 55)) + + addConstraint(NSLayoutConstraint(item: rotateCamera, attribute: .Height, + relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, + multiplier: 1, constant: 55)) } } @@ -93,9 +101,9 @@ extension ImagePickerController { let attributes: [NSLayoutAttribute] = [.Bottom, .Right, .Width] let topViewAttributes: [NSLayoutAttribute] = [.Left, .Top, .Width] - attributes.map { - self.view.addConstraint(NSLayoutConstraint(item: self.bottomContainer, attribute: $0, - relatedBy: .Equal, toItem: self.view, attribute: $0, + for attribute in attributes { + view.addConstraint(NSLayoutConstraint(item: bottomContainer, attribute: attribute, + relatedBy: .Equal, toItem: view, attribute: attribute, multiplier: 1, constant: 0)) } @@ -109,9 +117,9 @@ extension ImagePickerController { multiplier: 1, constant: 0)) } - topViewAttributes.map { - self.view.addConstraint(NSLayoutConstraint(item: self.topView, attribute: $0, - relatedBy: .Equal, toItem: self.view, attribute: $0, + for attribute in topViewAttributes { + view.addConstraint(NSLayoutConstraint(item: topView, attribute: attribute, + relatedBy: .Equal, toItem: self.view, attribute: attribute, multiplier: 1, constant: 0)) } @@ -146,4 +154,4 @@ extension ImageGalleryViewCell { constraintsAdded = true } } -} \ No newline at end of file +} diff --git a/Source/ImageGallery/ImageGalleryView.swift b/Source/ImageGallery/ImageGalleryView.swift index b96c74da..2cf3e092 100644 --- a/Source/ImageGallery/ImageGalleryView.swift +++ b/Source/ImageGallery/ImageGalleryView.swift @@ -25,7 +25,7 @@ public class ImageGalleryView: UIView { lazy public var collectionView: UICollectionView = { [unowned self] in let collectionView = UICollectionView(frame: CGRectMake(0, 0, 0, 0), collectionViewLayout: self.collectionViewLayout) - collectionView.setTranslatesAutoresizingMaskIntoConstraints(false) + collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.backgroundColor = self.configuration.mainColor collectionView.showsHorizontalScrollIndicator = false collectionView.layer.anchorPoint = CGPointMake(0.5, 0.5) @@ -45,7 +45,7 @@ public class ImageGalleryView: UIView { lazy var topSeparator: UIView = { [unowned self] in let view = UIView() - view.setTranslatesAutoresizingMaskIntoConstraints(false) + view.translatesAutoresizingMaskIntoConstraints = false view.addGestureRecognizer(self.panGestureRecognizer) view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6) @@ -56,7 +56,7 @@ public class ImageGalleryView: UIView { let view = UIView() view.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.6) view.layer.cornerRadius = Dimensions.indicatorHeight / 2 - view.setTranslatesAutoresizingMaskIntoConstraints(false) + view.translatesAutoresizingMaskIntoConstraints = false return view }() @@ -105,14 +105,16 @@ public class ImageGalleryView: UIView { collectionView.registerClass(ImageGalleryViewCell.self, forCellWithReuseIdentifier: CollectionView.reusableIdentifier) - [collectionView, topSeparator].map { self.addSubview($0) } + for view in [collectionView, topSeparator] { + addSubview(view) + } topSeparator.addSubview(indicator) imagesBeforeLoading = 0 fetchPhotos(0) } - required public init(coder aDecoder: NSCoder) { + required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -149,10 +151,11 @@ public class ImageGalleryView: UIView { let size = CGSizeMake(100, 150) if authorizationStatus == .Authorized { - if let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) { - if fetchResult.count != 0 && index < fetchResult.count { - imageManager.requestImageForAsset(fetchResult.objectAtIndex(fetchResult.count - 1 - index) as! PHAsset, targetSize: size, contentMode: PHImageContentMode.AspectFill, options: requestOptions, resultHandler: { (image, _) in - dispatch_async(dispatch_get_main_queue()) { + let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) + if fetchResult.count != 0 && index < fetchResult.count { + imageManager.requestImageForAsset(fetchResult.objectAtIndex(fetchResult.count - 1 - index) as! PHAsset, targetSize: size, contentMode: PHImageContentMode.AspectFill, options: requestOptions, resultHandler: { (image, _) in + dispatch_async(dispatch_get_main_queue()) { + if let image = image { if !self.images.containsObject(image) { self.images.addObject(image) if index > self.imagesBeforeLoading + 10 { @@ -166,8 +169,8 @@ public class ImageGalleryView: UIView { } } } + } }) - } } } } diff --git a/Source/ImageGallery/ImageGalleryViewCell.swift b/Source/ImageGallery/ImageGalleryViewCell.swift index af7adff1..3c887b94 100644 --- a/Source/ImageGallery/ImageGalleryViewCell.swift +++ b/Source/ImageGallery/ImageGalleryViewCell.swift @@ -22,7 +22,7 @@ class ImageGalleryViewCell: UICollectionViewCell { if imageView.superview != contentView { for view in [imageView, selectedImageView] { view.contentMode = .ScaleAspectFill - view.setTranslatesAutoresizingMaskIntoConstraints(false) + view.translatesAutoresizingMaskIntoConstraints = false view.clipsToBounds = true contentView.addSubview(view) } diff --git a/Source/ImageGallery/ImageGalleryViewDataSource.swift b/Source/ImageGallery/ImageGalleryViewDataSource.swift index 20ee4fa8..d306b1bf 100644 --- a/Source/ImageGallery/ImageGalleryViewDataSource.swift +++ b/Source/ImageGallery/ImageGalleryViewDataSource.swift @@ -22,7 +22,7 @@ extension ImageGalleryView: UICollectionViewDataSource { if indexPath.row == 0 && shouldTransform { cell.transform = CGAffineTransformMakeScale(0, 0) - UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .CurveEaseInOut, animations: { [unowned self] in + UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .CurveEaseInOut, animations: { cell.transform = CGAffineTransformIdentity }, completion: nil) diff --git a/Source/ImagePickerController.swift b/Source/ImagePickerController.swift index a845d097..7d3cece0 100644 --- a/Source/ImagePickerController.swift +++ b/Source/ImagePickerController.swift @@ -19,8 +19,6 @@ public class ImagePickerController: UIViewController { static let velocity: CGFloat = 100 } - public var stack = ImageStack() - lazy public var galleryView: ImageGalleryView = { [unowned self] in let galleryView = ImageGalleryView() galleryView.delegate = self @@ -45,11 +43,6 @@ public class ImagePickerController: UIViewController { return view }() - lazy var configuration: PickerConfiguration = { - let configuration = PickerConfiguration() - return configuration - }() - lazy var cameraController: CameraView = { [unowned self] in let controller = CameraView() controller.delegate = self @@ -57,12 +50,22 @@ public class ImagePickerController: UIViewController { return controller }() + lazy var panGestureRecognizer: UIPanGestureRecognizer = { [unowned self] in + let gesture = UIPanGestureRecognizer() + gesture.addTarget(self, action: "panGestureRecognizerHandler:") + + return gesture + }() + + lazy var configuration: PickerConfiguration = PickerConfiguration() + + public weak var delegate: ImagePickerDelegate? + public var stack = ImageStack() let totalHeight = UIScreen.mainScreen().bounds.size.height let totalWidth = UIScreen.mainScreen().bounds.size.width var initialFrame: CGRect! var initialContentOffset: CGPoint! var numberOfCells: Int! - public weak var delegate: ImagePickerDelegate? public var doneButtonTitle: String? { didSet { @@ -77,11 +80,12 @@ public class ImagePickerController: UIViewController { for subview in [cameraController.view, galleryView, bottomContainer, topView] { view.addSubview(subview) - subview.setTranslatesAutoresizingMaskIntoConstraints(false) + subview.translatesAutoresizingMaskIntoConstraints = false } view.backgroundColor = .whiteColor() view.backgroundColor = self.configuration.mainColor + cameraController.view.addGestureRecognizer(panGestureRecognizer) subscribe() setupConstraints() @@ -275,6 +279,19 @@ extension ImagePickerController: ImageGalleryPanGestureDelegate { numberOfCells = Int(initialContentOffset.x / galleryView.collectionSize.width) } + func panGestureRecognizerHandler(gesture: UIPanGestureRecognizer) { + let translation = gesture.translationInView(view) + let velocity = gesture.velocityInView(view) + + if gesture.locationInView(view).y > galleryView.frame.origin.y - 25 { + gesture.state == .Began ? panGestureDidStart() : panGestureDidChange(translation) + } + + if gesture.state == .Ended { + panGestureDidEnd(translation, velocity: velocity) + } + } + func panGestureDidChange(translation: CGPoint) { let galleryHeight = initialFrame.height - translation.y @@ -293,7 +310,7 @@ extension ImagePickerController: ImageGalleryPanGestureDelegate { galleryView.collectionSize = CGSize(width: galleryView.collectionView.frame.height, height: galleryView.collectionView.frame.height) if galleryHeight < GestureConstants.maximumHeight { - var realTranslation = translation.y < -GestureConstants.minimumHeight + ImageGalleryView.Dimensions.galleryBarHeight + let realTranslation = translation.y < -GestureConstants.minimumHeight + ImageGalleryView.Dimensions.galleryBarHeight ? translation.y + GestureConstants.minimumHeight - ImageGalleryView.Dimensions.galleryBarHeight : translation.y galleryView.collectionView.contentOffset = CGPoint(x: initialContentOffset.x - (realTranslation * CGFloat(numberOfCells)), y: 0) diff --git a/Source/TopView/TopView.swift b/Source/TopView/TopView.swift index 0b9bbef7..2b38e9a1 100644 --- a/Source/TopView/TopView.swift +++ b/Source/TopView/TopView.swift @@ -10,7 +10,7 @@ class TopView: UIView { struct Dimensions { static let leftOffset: CGFloat = 11 - static let rightOffset: CGFloat = 11 + static let rightOffset: CGFloat = 7 static let height: CGFloat = 34 } @@ -32,6 +32,7 @@ class TopView: UIView { let button = UIButton() button.setImage(self.getImage("cameraIcon"), forState: .Normal) button.addTarget(self, action: "rotateCameraButtonDidPress:", forControlEvents: .TouchUpInside) + button.imageView?.contentMode = .Center return button }() @@ -53,14 +54,14 @@ class TopView: UIView { button.layer.shadowOpacity = 0.5 button.layer.shadowOffset = CGSize(width: 0, height: 1) button.layer.shadowRadius = 1 - button.setTranslatesAutoresizingMaskIntoConstraints(false) + button.translatesAutoresizingMaskIntoConstraints = false addSubview(button) } setupConstraints() } - required init(coder aDecoder: NSCoder) { + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }