123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- //
- // CameraViewControllerConstraint.swift
- // CameraViewControllerConstraint
- //
- // Created by Pedro Paulo de Amorim.
- // Copyright (c) 2016 zero. All rights reserved.
- //
- // Modified by Kevin Kieffer on 2019/08/06. Changes as follows:
- // Changed configCameraOverlayWidthConstraint() to use a multipler to provide a rectangle instead of a square,
- // the rectangle being created by using an aspect ratio from the CroppingParameters
- //
- // Cleaned up the constraints for the flash, swap, and library buttons to work properly in both landscape orientations
- import UIKit
- import AVFoundation
- /**
- * This extension provides the configuration of
- * constraints for CameraViewController.
- */
- extension CameraViewController {
-
- /**
- * To attach the view to the edges of the superview, it needs
- to be pinned on the sides of the self.view, based on the
- edges of this superview.
- * This configure the cameraView to show, in real time, the
- * camera.
- */
- func configCameraViewConstraints() {
- [.left, .right, .top, .bottom].forEach({
- view.addConstraint(NSLayoutConstraint(
- item: cameraView,
- attribute: $0,
- relatedBy: .equal,
- toItem: view,
- attribute: $0,
- multiplier: 1.0,
- constant: 0))
- })
- }
-
- func removeCameraButtonConstraints() {
- view.autoRemoveConstraint(cameraButtonEdgeConstraint)
- view.autoRemoveConstraint(cameraButtonGravityConstraint)
- }
-
- /**
- * Add the constraints based on the device orientation,
- * this pin the button on the bottom part of the screen
- * when the device is portrait, when landscape, pin
- * the button on the right part of the screen.
- */
- func configCameraButtonEdgeConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
-
- let attribute : NSLayoutConstraint.Attribute = {
- switch statusBarOrientation {
- case .portrait: return .bottom
- case .landscapeRight: return .right
- case .landscapeLeft: return .left
- default: return .top
- }
- }()
- let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeRight
-
- cameraButtonEdgeConstraint = NSLayoutConstraint(
- item: cameraButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: constraintPortrait ? -16 : 16)
-
- view.addConstraint(cameraButtonEdgeConstraint!)
- }
-
- /**
- * Add the constraints based on the device orientation,
- * centerX the button based on the width of screen.
- * When the device is landscape orientation, centerY
- * the button based on the height of screen.
- */
- func configCameraButtonGravityConstraint(_ portrait: Bool) {
- let attribute : NSLayoutConstraint.Attribute = portrait ? .centerX : .centerY
- cameraButtonGravityConstraint = NSLayoutConstraint(
- item: cameraButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(cameraButtonGravityConstraint!)
- }
-
- /**
- * Remove the constraints of container.
- */
- func removeContainerConstraints() {
- view.autoRemoveConstraint(containerButtonsEdgeOneConstraint)
- view.autoRemoveConstraint(containerButtonsEdgeTwoConstraint)
- view.autoRemoveConstraint(containerButtonsGravityConstraint)
- }
-
- /**
- * Configure the edges constraints of container that
- * handle the center position of SwapButton and
- * LibraryButton.
- */
- func configContainerEdgeConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
-
- let attributeOne : NSLayoutConstraint.Attribute
- let attributeTwo : NSLayoutConstraint.Attribute
-
- switch statusBarOrientation {
- case .portrait:
- attributeOne = .left
- attributeTwo = .right
- break
- case .landscapeRight:
- attributeOne = .bottom
- attributeTwo = .top
- break
- case .landscapeLeft:
- attributeOne = .top
- attributeTwo = .bottom
- break
- default:
- attributeOne = .right
- attributeTwo = .left
- break
- }
-
- containerButtonsEdgeOneConstraint = NSLayoutConstraint(
- item: containerSwapLibraryButton,
- attribute: attributeOne,
- relatedBy: .equal,
- toItem: cameraButton,
- attribute: attributeTwo,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(containerButtonsEdgeOneConstraint!)
-
- containerButtonsEdgeTwoConstraint = NSLayoutConstraint(
- item: containerSwapLibraryButton,
- attribute: attributeTwo,
- relatedBy: .equal,
- toItem: view,
- attribute: attributeTwo,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(containerButtonsEdgeTwoConstraint!)
- }
-
- /**
- * Configure the gravity of container, based on the
- * orientation of the device.
- */
- func configContainerGravityConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
- let attributeCenter : NSLayoutConstraint.Attribute = statusBarOrientation.isPortrait ? .centerY : .centerX
- containerButtonsGravityConstraint = NSLayoutConstraint(
- item: containerSwapLibraryButton,
- attribute: attributeCenter,
- relatedBy: .equal,
- toItem: cameraButton,
- attribute: attributeCenter,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(containerButtonsGravityConstraint!)
- }
-
- /**
- * Remove the SwapButton constraints to be updated when
- * the device was rotated.
- */
- func removeSwapButtonConstraints() {
- view.autoRemoveConstraint(swapButtonEdgeOneConstraint)
- view.autoRemoveConstraint(swapButtonEdgeTwoConstraint)
- view.autoRemoveConstraint(swapButtonGravityConstraint)
- }
-
- /**
- * If the device is portrait, pin the SwapButton on the
- * right side of the CameraButton.
- * If landscape, pin the SwapButton on the top of the
- * CameraButton.
- */
- func configSwapButtonEdgeConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
-
- let attributeOne : NSLayoutConstraint.Attribute
- let attributeTwo : NSLayoutConstraint.Attribute
- switch statusBarOrientation {
- case .portrait:
- attributeOne = .top
- attributeTwo = .bottom
- break
- case .landscapeRight:
- attributeOne = .left
- attributeTwo = .right
- break
- case .landscapeLeft:
- attributeOne = .right
- attributeTwo = .left
- break
- default:
- attributeOne = .bottom
- attributeTwo = .top
- break
- }
-
- swapButtonEdgeOneConstraint = NSLayoutConstraint(
- item: swapButton,
- attribute: attributeOne,
- relatedBy: .equal,
- toItem: containerSwapLibraryButton,
- attribute: attributeOne,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(swapButtonEdgeOneConstraint!)
-
- swapButtonEdgeTwoConstraint = NSLayoutConstraint(
- item: swapButton,
- attribute: attributeTwo,
- relatedBy: .equal,
- toItem: containerSwapLibraryButton,
- attribute: attributeTwo,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(swapButtonEdgeTwoConstraint!)
-
- }
-
- /**
- * Configure the center of SwapButton, based on the
- * axis center of CameraButton.
- */
- func configSwapButtonGravityConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
-
- let portrait = statusBarOrientation == .portrait
- let landLeft = statusBarOrientation == .landscapeLeft
-
- swapButtonGravityConstraint = NSLayoutConstraint(
- item: swapButton,
- attribute: portrait ? .right : (landLeft ? .bottom : .top),
- relatedBy: portrait || landLeft ? .lessThanOrEqual : .greaterThanOrEqual,
- toItem: containerSwapLibraryButton,
- attribute: portrait ? .centerX : .centerY,
- multiplier: 1.0,
- constant: (portrait || landLeft ? -4.0 : 4.0) * DeviceConfig.SCREEN_MULTIPLIER)
- view.addConstraint(swapButtonGravityConstraint!)
- }
-
- func removeCloseButtonConstraints() {
- view.autoRemoveConstraint(closeButtonEdgeConstraint)
- view.autoRemoveConstraint(closeButtonGravityConstraint)
- }
-
- /**
- * Pin the close button to the left of the superview.
- */
- func configCloseButtonEdgeConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
-
- let attribute : NSLayoutConstraint.Attribute = {
- switch statusBarOrientation {
- case .portrait: return .left
- case .landscapeRight, .landscapeLeft: return .centerX
- default: return .right
- }
- }()
- closeButtonEdgeConstraint = NSLayoutConstraint(
- item: closeButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: attribute != .centerX ? view : cameraButton,
- attribute: attribute,
- multiplier: 1.0,
- constant: attribute != .centerX ? 16 : 0)
- view.addConstraint(closeButtonEdgeConstraint!)
- }
-
- /**
- * Add the constraint for the CloseButton, based on
- * the device orientation.
- * If portrait, it pin the CloseButton on the CenterY
- * of the CameraButton.
- * Else if landscape, pin this button on the Bottom
- * of superview.
- */
- func configCloseButtonGravityConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
-
- let attribute : NSLayoutConstraint.Attribute
- let constant : CGFloat
-
- switch statusBarOrientation {
- case .portrait:
- attribute = .centerY
- constant = 0.0
- break
- case .landscapeRight:
- attribute = .bottom
- constant = -16.0
- break
- case .landscapeLeft:
- attribute = .top
- constant = 16.0
- break
- default:
- attribute = .centerX
- constant = 0.0
- break
- }
-
- closeButtonGravityConstraint = NSLayoutConstraint(
- item: closeButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: attribute == .bottom || attribute == .top ? view : cameraButton,
- attribute: attribute,
- multiplier: 1.0,
- constant: constant)
-
- view.addConstraint(closeButtonGravityConstraint!)
- }
-
- /**
- * Remove the LibraryButton constraints to be updated when
- * the device was rotated.
- */
- func removeLibraryButtonConstraints() {
- view.autoRemoveConstraint(libraryButtonEdgeOneConstraint)
- view.autoRemoveConstraint(libraryButtonEdgeTwoConstraint)
- view.autoRemoveConstraint(libraryButtonGravityConstraint)
- }
-
- /**
- * Add the constraint of the LibraryButton, if the device
- * orientation is portrait, pin the right side of SwapButton
- * to the left side of LibraryButton.
- * If landscape, pin the bottom side of CameraButton on the
- * top side of LibraryButton.
- */
- func configLibraryEdgeButtonConstraint(_ statusBarOrientation : UIInterfaceOrientation) {
- let attributeOne : NSLayoutConstraint.Attribute
- let attributeTwo : NSLayoutConstraint.Attribute
-
- switch statusBarOrientation {
- case .portrait:
- attributeOne = .top
- attributeTwo = .bottom
- break
- case .landscapeRight:
- attributeOne = .left
- attributeTwo = .right
- break
- case .landscapeLeft:
- attributeOne = .right
- attributeTwo = .left
- break
- default:
- attributeOne = .bottom
- attributeTwo = .top
- break
- }
-
- libraryButtonEdgeOneConstraint = NSLayoutConstraint(
- item: libraryButton,
- attribute: attributeOne,
- relatedBy: .equal,
- toItem: containerSwapLibraryButton,
- attribute: attributeOne,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(libraryButtonEdgeOneConstraint!)
-
- libraryButtonEdgeTwoConstraint = NSLayoutConstraint(
- item: libraryButton,
- attribute: attributeTwo,
- relatedBy: .equal,
- toItem: containerSwapLibraryButton,
- attribute: attributeTwo,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(libraryButtonEdgeTwoConstraint!)
-
- }
-
- /**
- * Set the center gravity of the LibraryButton based
- * on the position of CameraButton.
- */
- func configLibraryGravityButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
-
- let portrait = statusBarOrientation == .portrait
- let landLeft = statusBarOrientation == .landscapeLeft
-
- libraryButtonGravityConstraint = NSLayoutConstraint(
- item: libraryButton,
- attribute: portrait ? .left : (landLeft ? .top : .bottom),
- relatedBy: portrait || landLeft ? .greaterThanOrEqual : .lessThanOrEqual,
- toItem: containerSwapLibraryButton,
- attribute: portrait ? .centerX : .centerY,
- multiplier: 1.0,
- constant: (portrait || landLeft ? 4.0 : -4.0) * DeviceConfig.SCREEN_MULTIPLIER)
- view.addConstraint(libraryButtonGravityConstraint!)
- }
-
- /**
- * If the device orientation is portrait, pin the top of
- * FlashButton to the top side of superview.
- * Else if, pin the FlashButton bottom side on the top side
- * of SwapButton.
- */
- func configFlashEdgeButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
- view.autoRemoveConstraint(flashButtonEdgeConstraint)
-
- let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeLeft
- let attribute : NSLayoutConstraint.Attribute = constraintPortrait ? .top : .left
-
- flashButtonEdgeConstraint = NSLayoutConstraint(
- item: flashButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: constraintPortrait ? 16 : 16)
- view.addConstraint(flashButtonEdgeConstraint!)
- }
-
- /**
- * If the device orientation is portrait, pin the
- right side of FlashButton to the right side of
- * superview.
- * Else if, centerX the FlashButton on the CenterX
- * of CameraButton.
- */
- func configFlashGravityButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
- view.autoRemoveConstraint(flashButtonGravityConstraint)
-
- let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeLeft
- let attribute : NSLayoutConstraint.Attribute = constraintPortrait ? .right : .top
-
- flashButtonGravityConstraint = NSLayoutConstraint(
- item: flashButton,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: constraintPortrait ? -16 : 16)
- view.addConstraint(flashButtonGravityConstraint!)
- }
-
- /**
- * Used to create a perfect was: square now: rectangle with aspect ratio for CameraOverlay.
- * This method will determinate the size of CameraOverlay,
- * if portrait, it will use the width of superview to
- * determinate the height of the view. Else if landscape,
- * it uses the height of the superview to create the width
- * of the CameraOverlay.
- */
- func configCameraOverlayWidthConstraint(_ portrait: Bool) {
- view.autoRemoveConstraint(cameraOverlayWidthConstraint)
- cameraOverlayWidthConstraint = NSLayoutConstraint(
- item: cameraOverlay,
- attribute: portrait ? .height : .width,
- relatedBy: .equal,
- toItem: cameraOverlay,
- attribute: portrait ? .width : .height,
- multiplier: portrait ? croppingParameters.aspectRatioHeightToWidth : 1.0/croppingParameters.aspectRatioHeightToWidth,
- constant: 0)
- view.addConstraint(cameraOverlayWidthConstraint!)
- }
-
- /**
- * This method will center the relative position of
- * CameraOverlay, based on the biggest size of the
- * superview.
- */
- func configCameraOverlayCenterConstraint(_ portrait: Bool) {
- view.autoRemoveConstraint(cameraOverlayCenterConstraint)
- let attribute : NSLayoutConstraint.Attribute = portrait ? .centerY : .centerX
- cameraOverlayCenterConstraint = NSLayoutConstraint(
- item: cameraOverlay,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: 0)
- view.addConstraint(cameraOverlayCenterConstraint!)
- }
-
- /**
- * Remove the CameraOverlay constraints to be updated when
- * the device was rotated.
- */
- func removeCameraOverlayEdgesConstraints() {
- view.autoRemoveConstraint(cameraOverlayEdgeOneConstraint)
- view.autoRemoveConstraint(cameraOverlayEdgeTwoConstraint)
- }
-
- /**
- * It needs to get a determined smallest size of the screen
- to create the smallest size to be used on CameraOverlay.
- It uses the orientation of the screen to determinate where
- the view will be pinned.
- */
- func configCameraOverlayEdgeOneContraint(_ portrait: Bool, padding: CGFloat) {
- let attribute : NSLayoutConstraint.Attribute = portrait ? .left : .bottom
- cameraOverlayEdgeOneConstraint = NSLayoutConstraint(
- item: cameraOverlay,
- attribute: attribute,
- relatedBy: .equal,
- toItem: view,
- attribute: attribute,
- multiplier: 1.0,
- constant: padding)
- view.addConstraint(cameraOverlayEdgeOneConstraint!)
- }
-
- /**
- * It needs to get a determined smallest size of the screen
- to create the smallest size to be used on CameraOverlay.
- It uses the orientation of the screen to determinate where
- the view will be pinned.
- */
- func configCameraOverlayEdgeTwoConstraint(_ portrait: Bool, padding: CGFloat) {
- let attributeTwo : NSLayoutConstraint.Attribute = portrait ? .right : .top
- cameraOverlayEdgeTwoConstraint = NSLayoutConstraint(
- item: cameraOverlay,
- attribute: attributeTwo,
- relatedBy: .equal,
- toItem: view,
- attribute: attributeTwo,
- multiplier: 1.0,
- constant: -padding)
- view.addConstraint(cameraOverlayEdgeTwoConstraint!)
- }
-
- }
|