我已经根据SwiftyCam在GitHub上的演示项目创建了我的摄像机视图,一切都布置正确并且进展顺利;但是,按下摄像机按钮时,控制台上会显示一条消息,提示“ [[SwiftyCam]:无法拍照。捕获会话未运行”。有人用swift 4遇到了这个问题,您可以找到here。我逐行浏览了整个框架,但是由于某种原因,我无法弄清楚。如果有人可以查看框架和文档并为我提供帮助,我将非常感激。我的操作方式与Swift 4 demo project中的操作方式完全相同,因此可以作为代码参考。
提前谢谢
编辑:以下是在WelcomeVC之后设置SwipeNavigationController时的代码
let swipeNavigationController = SwipeNavigationController(centerViewController: CameraViewController())
swipeNavigationController.topViewController = BlueView()
swipeNavigationController.bottomViewController = PinkView()
swipeNavigationController.leftViewController = OrangeView()
swipeNavigationController.rightViewController = GreenView()
cameraView.navigationController?.setNavigationBarHidden(true, animated: false)
orangeView.navigationController?.setNavigationBarHidden(false, animated: false)
greenView.navigationController?.setNavigationBarHidden(false, animated: false)
let navController = UINavigationController(rootViewController: swipeNavigationController)
self.present(navController, animated: true, completion: nil)
下面是CameraVC中的所有代码
class CameraViewController: SwiftyCamViewController, SwiftyCamViewControllerDelegate, SwipeNavigationControllerDelegate {
let orangeVC = OrangeView()
let greenVC = GreenView()
let blueVC = BlueView()
let pinkVC = PinkView()
let flipCameraButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "cameraSwitch")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(cameraSwitchTapped), for: .touchUpInside)
return button
}()
let captureButton: SwiftyRecordButton = {
let button = SwiftyRecordButton(frame: CGRect(x: 150, y: 572, width: 75, height: 75))
//let image = UIImage(named: "focus")
//button.setImage(image, for: .normal)
//button.addTarget(self, action: #selector(cameraTapped), for: .touchUpInside)
return button
}()
let orangeButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "OrangeIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToOrange), for: .touchUpInside)
return button
}()
let greenButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "GreenIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToGreen), for: .touchUpInside)
return button
}()
let pinkButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "pinkCameraIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToPink), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(flipCameraButton)
view.addSubview(captureButton)
view.addSubview(orangeButton)
view.addSubview(greenButton)
view.addSubview(pinkButton)
shouldPrompToAppSettings = true
cameraDelegate = self
maximumVideoDuration = 10.0
shouldUseDeviceOrientation = true
allowAutoRotate = true
audioEnabled = true
// disable capture button until session starts
captureButton.buttonEnabled = false
navigationController?.isNavigationBarHidden = true
UIApplication.shared.statusBarStyle = .lightContent
navigationController?.isNavigationBarHidden = true
setupViews()
}
override func viewWillAppear(_ animated: Bool) {
UIApplication.shared.statusBarStyle = .lightContent
navigationController?.isNavigationBarHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
captureButton.delegate = self
}
//
@objc func goToOrange() {
orangeVC.navigationController?.setNavigationBarHidden(false, animated: true)
self.containerSwipeNavigationController?.showEmbeddedView(position: .left)
}
@objc func goToGreen() {
greenVC.navigationController?.setNavigationBarHidden(false, animated: true)
self.containerSwipeNavigationController?.showEmbeddedView(position: .right)
}
@objc func goToPink() {
self.containerSwipeNavigationController?.showEmbeddedView(position: .bottom)
}
@objc func cameraSwitchTapped() {
switchCamera()
}
@objc func cameraTapped() {
print("CAMERA TAPPED")
takePhoto()
}
func setupViews() {
flipCameraButton.anchor(top: view.topAnchor, left: nil, bottom: nil, right: view.rightAnchor, paddingTop: 25, paddingLeft: 0, paddingBottom: 0, paddingRight: 12, width: 35, height: 35)
captureButton.anchor(top: nil, left: nil, bottom: pinkButton.topAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 10, paddingRight: 0, width: 75, height: 75)
captureButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
orangeButton.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 10, paddingBottom: 0, paddingRight: 0, width: 75, height: 75)
greenButton.anchor(top: nil, left: nil, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 10, width: 75, height: 75)
pinkButton.anchor(top: nil, left: nil, bottom: view.bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: -10, paddingRight: 0, width: 75, height: 75)
pinkButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
view.addSubview(flipCameraButton)
view.addSubview(captureButton)
view.addSubview(orangeButton)
view.addSubview(greenButton)
view.addSubview(pinkButton)
}
//MARK: Camera Protocols
func swiftyCamSessionDidStartRunning(_ swiftyCam: SwiftyCamViewController) {
print("Session did start running")
captureButton.buttonEnabled = true
}
func swiftyCamSessionDidStopRunning(_ swiftyCam: SwiftyCamViewController) {
print("Session did stop running")
captureButton.buttonEnabled = false
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
let newVC = AfterPhotoTakenView(image: photo)
self.present(newVC, animated: true, completion: nil)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
print("Did Begin Recording")
captureButton.growButton()
hideButtons()
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
print("Did finish Recording")
captureButton.shrinkButton()
showButtons()
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) {
let newVC = VideoView(videoURL: url)
self.present(newVC, animated: true, completion: nil)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFocusAtPoint point: CGPoint) {
print("Did focus at point: \(point)")
focusAnimationAt(point)
}
func swiftyCamDidFailToConfigure(_ swiftyCam: SwiftyCamViewController) {
let message = NSLocalizedString("Unable to capture media", comment: "Alert message when something goes wrong during capture session configuration")
let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil))
present(alertController, animated: true, completion: nil)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didChangeZoomLevel zoom: CGFloat) {
print("Zoom level did change. Level: \(zoom)")
print(zoom)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didSwitchCameras camera: SwiftyCamViewController.CameraSelection) {
print("Camera did change to \(camera.rawValue)")
print(camera)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFailToRecordVideo error: Error) {
print(error)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
extension CameraViewController {
fileprivate func hideButtons() {
UIView.animate(withDuration: 0.25) {
self.flipCameraButton.alpha = 0.0
}
}
fileprivate func showButtons() {
UIView.animate(withDuration: 0.25) {
self.flipCameraButton.alpha = 1.0
}
}
fileprivate func focusAnimationAt(_ point: CGPoint) {
let focusView = UIImageView(image: #imageLiteral(resourceName: "focus"))
focusView.center = point
focusView.alpha = 0.0
view.addSubview(focusView)
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
focusView.alpha = 1.0
focusView.transform = CGAffineTransform(scaleX: 1.25, y: 1.25)
}) { (success) in
UIView.animate(withDuration: 0.15, delay: 0.5, options: .curveEaseInOut, animations: {
focusView.alpha = 0.0
focusView.transform = CGAffineTransform(translationX: 0.6, y: 0.6)
}) { (success) in
focusView.removeFromSuperview()
}
}
}
fileprivate func toggleFlashAnimation() {
if flashEnabled == true {
//flashButton.setImage(#imageLiteral(resourceName: "flash"), for: UIControlState())
} else {
//flashButton.setImage(#imageLiteral(resourceName: "flashOutline"), for: UIControlState())
}
}
}
这是用户滑动到另一个视图时的外观,并且按钮没有响应,并且用户也无法向上或向下滑动这些视图。
这是当用户从左向右滑动或单击粉红色的消息按钮时我要呈现的视图的示例。
class MessagesView: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
setupNavBar()
navigationController?.isNavigationBarHidden = false
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
} else {
// Fallback on earlier versions
}
}
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
setupNavBar()
} else {
setupNavBar()
}
}
func setupNavBar() {
UIApplication.shared.statusBarStyle = .lightContent
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.topItem?.title = "Messages"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
self.navigationController?.navigationBar.barTintColor = UIColor.pinkNeonColor
self.navigationController?.navigationBar.tintColor = UIColor.white
}
}
答案 0 :(得分:2)
public enum Position {
case center
case top
case bottom
case left
case right
}
enum ActivePanDirection {
case undefined
case horizontal
case vertical
}
public protocol SwipeNavigationControllerDelegate: class {
func swipeNavigationController(_ controller: SwipeNavigationController, willShowEmbeddedViewForPosition position: Position)
func swipeNavigationController(_ controller: SwipeNavigationController, didShowEmbeddedViewForPosition position: Position)
}
open class SwipeNavigationController: SwiftyCamViewController, SwiftyCamViewControllerDelegate {
@IBOutlet fileprivate var currentXOffset: NSLayoutConstraint!
@IBOutlet fileprivate var currentYOffset: NSLayoutConstraint!
open fileprivate(set) weak var activeViewController: UIViewController!
public weak var delegate: SwipeNavigationControllerDelegate?
open fileprivate(set) var centerViewController: UIViewController!
open var topViewController: UIViewController? {
willSet(newValue) {
self.shouldShowTopViewController = newValue != nil
guard let viewController = newValue else {
return
}
addEmbeddedViewController(viewController, previousViewController: topViewController, position: .top)
}
}
open var bottomViewController: UIViewController? {
willSet(newValue) {
self.shouldShowBottomViewController = newValue != nil
guard let viewController = newValue else {
return
}
addEmbeddedViewController(viewController, previousViewController: bottomViewController, position: .bottom)
}
}
open var leftViewController: UIViewController? {
willSet(newValue) {
self.shouldShowLeftViewController = newValue != nil
guard let viewController = newValue else {
return
}
addEmbeddedViewController(viewController, previousViewController: leftViewController, position: .left)
}
}
open var rightViewController: UIViewController? {
willSet(newValue) {
self.shouldShowRightViewController = newValue != nil
guard let viewController = newValue else {
return
}
addEmbeddedViewController(viewController, previousViewController: rightViewController, position: .right)
}
}
open override var shouldAutomaticallyForwardAppearanceMethods: Bool {
get {
return false
}
}
@IBOutlet fileprivate var mainPanGesture: UIPanGestureRecognizer!
fileprivate var previousNonZeroDirectionChange = CGVector(dx: 0.0, dy: 0.0)
fileprivate var activePanDirection = ActivePanDirection.undefined
fileprivate let verticalSnapThresholdFraction: CGFloat = 0.15
fileprivate let horizontalSnapThresholdFraction: CGFloat = 0.15
fileprivate var centerContainerOffset: CGVector!
fileprivate var topContainerOffset: CGVector!
fileprivate var bottomContainerOffset: CGVector!
fileprivate var leftContainerOffset: CGVector!
fileprivate var rightContainerOffset: CGVector!
open var shouldShowTopViewController = true
open var shouldShowBottomViewController = true
open var shouldShowLeftViewController = true
open var shouldShowRightViewController = true
open var shouldShowCenterViewController = true
fileprivate let swipeAnimateDuration = 0.2
public init(centerViewController: UIViewController) {
super.init(nibName: nil, bundle: nil)
shouldShowTopViewController = false
shouldShowBottomViewController = false
shouldShowLeftViewController = false
shouldShowRightViewController = false
self.centerViewController = centerViewController
addChildViewController(centerViewController)
centerViewController.didMove(toParentViewController: self)
}
public func swiftyCamSessionDidStartRunning(_ swiftyCam: SwiftyCamViewController) {
print("Session did start running")
captureButton.buttonEnabled = true
}
public func swiftyCamSessionDidStopRunning(_ swiftyCam: SwiftyCamViewController) {
print("Session did stop running")
captureButton.buttonEnabled = false
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
let newVC = PhotoViewController(image: photo)
self.present(newVC, animated: true, completion: nil)
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
print("Did Begin Recording")
captureButton.growButton()
hideButtons()
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
print("Did finish Recording")
captureButton.shrinkButton()
showButtons()
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) {
let newVC = VideoViewController(videoURL: url)
self.present(newVC, animated: true, completion: nil)
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFocusAtPoint point: CGPoint) {
print("Did focus at point: \(point)")
focusAnimationAt(point)
}
public func swiftyCamDidFailToConfigure(_ swiftyCam: SwiftyCamViewController) {
let message = NSLocalizedString("Unable to capture media", comment: "Alert message when something goes wrong during capture session configuration")
let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil))
present(alertController, animated: true, completion: nil)
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didChangeZoomLevel zoom: CGFloat) {
print("Zoom level did change. Level: \(zoom)")
print(zoom)
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didSwitchCameras camera: SwiftyCamViewController.CameraSelection) {
print("Camera did change to \(camera.rawValue)")
print(camera)
}
public func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFailToRecordVideo error: Error) {
print(error)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
let flipCameraButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "cameraSwitch")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(cameraSwitchTapped), for: .touchUpInside)
return button
}()
let captureButton: SwiftyRecordButton = {
let button = SwiftyRecordButton(frame: CGRect(x: 150, y: 572, width: 75, height: 75))
let image = UIImage(named: "focus")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(cameraTapped), for: .touchUpInside)
return button
}()
let orangeButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "OrangeIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToOrange), for: .touchUpInside)
return button
}()
let greenButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "GreenIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToGreen), for: .touchUpInside)
return button
}()
let pinkButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "pinkCameraIcon")
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(goToPink), for: .touchUpInside)
return button
}()
@objc func goToOrange() {
//orangeVC.navigationController?.setNavigationBarHidden(false, animated: true)
self.containerSwipeNavigationController?.showEmbeddedView(position: .left)
}
@objc func goToGreen() {
//greenVC.navigationController?.setNavigationBarHidden(false, animated: true)
self.containerSwipeNavigationController?.showEmbeddedView(position: .right)
}
@objc func goToPink() {
self.containerSwipeNavigationController?.showEmbeddedView(position: .bottom)
}
@objc func cameraSwitchTapped() {
switchCamera()
}
@objc func cameraTapped() {
print("CAMERA TAPPED")
takePhoto()
}
// Mark: - Functions
open override func viewDidLoad() {
super.viewDidLoad()
self.cameraDelegate = self
if currentXOffset == nil && currentYOffset == nil {
view.addSubview(centerViewController.view)
centerViewController.view.isHidden = true
centerViewController.view.translatesAutoresizingMaskIntoConstraints = false
self.currentXOffset = alignCenterXConstraint(forItem: centerViewController.view, toItem: view, position: .center)
self.currentYOffset = alignCenterYConstraint(forItem: centerViewController.view, toItem: view, position: .center)
view.addConstraints([self.currentXOffset, self.currentYOffset])
view.addConstraints(sizeConstraints(forItem: centerViewController.view, toItem: view))
}
testViewdid()
assert(currentXOffset != nil && currentYOffset != nil, "both currentXOffset and currentYOffset must be set")
if mainPanGesture == nil {
mainPanGesture = UIPanGestureRecognizer(target: self, action: #selector(onPanGestureTriggered(sender:)))
view.addGestureRecognizer(mainPanGesture)
}
let frameWidth = view.frame.size.width
let frameHeight = view.frame.size.height
centerContainerOffset = CGVector(dx: currentXOffset.constant, dy: currentYOffset.constant)
topContainerOffset = CGVector(dx: centerContainerOffset.dx, dy: centerContainerOffset.dy + frameHeight)
bottomContainerOffset = CGVector(dx: centerContainerOffset.dx, dy: centerContainerOffset.dy - frameHeight)
leftContainerOffset = CGVector(dx: centerContainerOffset.dx + frameWidth, dy: centerContainerOffset.dy)
rightContainerOffset = CGVector(dx: centerContainerOffset.dx - frameWidth, dy: centerContainerOffset.dy)
activeViewController = centerViewController
}
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
activeViewController.beginAppearanceTransition(true, animated: animated)
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
activeViewController.endAppearanceTransition()
captureButton.delegate = self
}
open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
activeViewController.beginAppearanceTransition(false, animated: animated)
}
open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
activeViewController.endAppearanceTransition()
}
func testViewdid() {
view.addSubview(flipCameraButton)
view.addSubview(captureButton)
view.addSubview(orangeButton)
view.addSubview(greenButton)
view.addSubview(pinkButton)
shouldPrompToAppSettings = true
cameraDelegate = self
maximumVideoDuration = 10.0
shouldUseDeviceOrientation = true
allowAutoRotate = true
audioEnabled = true
captureButton.buttonEnabled = true
navigationController?.isNavigationBarHidden = true
UIApplication.shared.statusBarStyle = .lightContent
navigationController?.isNavigationBarHidden = true
//setupViews()
}
// Let UIKit handle rotation forwarding calls
open override func shouldAutomaticallyForwardRotationMethods() -> Bool {
return true
}
// MARK: - Containers
open func showEmbeddedView(position: Position) {
weak var disappearingViewController: UIViewController?
let targetOffset: CGVector
switch position {
case .center:
if !activeViewController.isEqual(centerViewController) {
disappearingViewController = activeViewController
}
activeViewController = centerViewController
targetOffset = centerContainerOffset
case .top:
activeViewController = topViewController
targetOffset = topContainerOffset
case .bottom:
activeViewController = bottomViewController
targetOffset = bottomContainerOffset
case .left:
activeViewController = leftViewController
targetOffset = leftContainerOffset
case .right:
activeViewController = rightViewController
targetOffset = rightContainerOffset
}
if !activeViewController.isEqual(centerViewController) {
disappearingViewController = centerViewController
}
currentXOffset.constant = targetOffset.dx
currentYOffset.constant = targetOffset.dy
disappearingViewController?.beginAppearanceTransition(false, animated: true)
activeViewController.beginAppearanceTransition(true, animated: true)
delegate?.swipeNavigationController(self, willShowEmbeddedViewForPosition: position)
UIView.animate(withDuration: swipeAnimateDuration, animations: {
self.view.layoutIfNeeded()
}) { (finished) in
self.delegate?.swipeNavigationController(self, didShowEmbeddedViewForPosition: position)
self.activeViewController.endAppearanceTransition()
disappearingViewController?.endAppearanceTransition()
}
}
open func isContainerActive(position: Position) -> Bool {
let targetOffset: CGVector
switch position {
case .center:
targetOffset = centerContainerOffset
case .top:
targetOffset = topContainerOffset
case .bottom:
targetOffset = bottomContainerOffset
case .left:
targetOffset = leftContainerOffset
case .right:
targetOffset = rightContainerOffset
}
return (currentXOffset.constant, currentYOffset.constant) == (targetOffset.dx, targetOffset.dy)
}
open func lock() {
self.mainPanGesture.isEnabled = false
}
open func unlock() {
self.mainPanGesture.isEnabled = true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return true
}
@IBAction fileprivate func onPanGestureTriggered(sender: UIPanGestureRecognizer) {
switch sender.state {
case .began:
if isContainerActive(position: .top) || isContainerActive(position: .bottom) {
activePanDirection = .vertical
} else if isContainerActive(position: .left) || isContainerActive(position: .right) {
activePanDirection = .horizontal
} else {
activePanDirection = .undefined
}
case .changed:
let translationInMainView = sender.translation(in: view)
if translationInMainView.x != 0 {
previousNonZeroDirectionChange.dx = translationInMainView.x
}
if translationInMainView.y != 0 {
previousNonZeroDirectionChange.dy = translationInMainView.y
}
switch activePanDirection {
case .undefined:
activePanDirection = fabs(translationInMainView.x) > fabs(translationInMainView.y) ? .horizontal : .vertical
case .horizontal:
let isCurrentlyShowingRightViewController = currentXOffset.constant < centerContainerOffset.dx
let isCurrentlyShowingLeftViewController = currentXOffset.constant > centerContainerOffset.dx
let minX = isCurrentlyShowingRightViewController || shouldShowRightViewController ? rightContainerOffset.dx : centerContainerOffset.dx
let maxX = isCurrentlyShowingLeftViewController || shouldShowLeftViewController ? leftContainerOffset.dx : centerContainerOffset.dx
if shouldShowCenterViewController {
currentXOffset.constant = min(max(minX, currentXOffset.constant + translationInMainView.x), maxX)
}
case .vertical:
let isCurrentlyShowingBottomViewController = currentYOffset.constant < centerContainerOffset.dy
let isCurrentlyShowingTopViewController = currentYOffset.constant > centerContainerOffset.dy
let minY = isCurrentlyShowingBottomViewController || shouldShowBottomViewController ? bottomContainerOffset.dy : centerContainerOffset.dy
let maxY = isCurrentlyShowingTopViewController || shouldShowTopViewController ? topContainerOffset.dy : centerContainerOffset.dy
if shouldShowCenterViewController {
currentYOffset.constant = min(max(minY, currentYOffset.constant + translationInMainView.y), maxY)
}
}
// reset translation for next iteration
sender.setTranslation(CGPoint.zero, in: view)
case .ended:
/*
* Handle snapping here
*/
switch activePanDirection {
case .horizontal:
if currentXOffset.constant > 0.0 {
// within range of center container
if currentXOffset.constant < (horizontalSnapThresholdFraction * view.frame.size.width) {
showEmbeddedView(position: .center)
}
// within range of left container
else if currentXOffset.constant > ((1.0 - horizontalSnapThresholdFraction) * view.frame.size.width) {
showEmbeddedView(position: .left)
}
// center region: depends on inertia direction
else {
// pulled right
if previousNonZeroDirectionChange.dx > 0.0 {
showEmbeddedView(position: .left)
}
// pulled left
else {
showEmbeddedView(position: .center)
}
}
}
else if currentXOffset.constant < 0.0 {
// within range of center container
if currentXOffset.constant > (horizontalSnapThresholdFraction * -view.frame.size.width) {
showEmbeddedView(position: .center)
}
// within range of right container
else if currentXOffset.constant < ((1.0 - horizontalSnapThresholdFraction) * -view.frame.size.width) {
showEmbeddedView(position: .right)
}
// center region: depends on inertia direction
else {
// pulled left
if previousNonZeroDirectionChange.dx < 0.0 {
showEmbeddedView(position: .right)
}
// pulled right
else {
showEmbeddedView(position: .center)
}
}
}
case .vertical:
if currentYOffset.constant > 0.0 {
if currentYOffset.constant < (verticalSnapThresholdFraction * view.frame.size.height) {
showEmbeddedView(position: .center)
}
else if currentYOffset.constant > ((1.0 - verticalSnapThresholdFraction) * view.frame.size.height) {
showEmbeddedView(position: .top)
}
else {
if previousNonZeroDirectionChange.dy > 0.0 {
showEmbeddedView(position: .top)
}
else {
showEmbeddedView(position: .center)
}
}
}
else if currentYOffset.constant < 0.0 {
if currentYOffset.constant > (verticalSnapThresholdFraction * -view.frame.size.height) {
showEmbeddedView(position: .center)
}
else if currentYOffset.constant < ((1.0 - verticalSnapThresholdFraction) * -view.frame.size.height) {
showEmbeddedView(position: .bottom)
}
else {
if previousNonZeroDirectionChange.dy < 0.0 {
showEmbeddedView(position: .bottom)
}
else {
showEmbeddedView(position: .center)
}
}
}
case .undefined:
break
}
default:
break
}
}
func addEmbeddedViewController(_ viewController: UIViewController, previousViewController: UIViewController?, position: Position) {
if viewController.isEqual(previousViewController) {
return
}
previousViewController?.beginAppearanceTransition(false, animated: false)
previousViewController?.view.removeFromSuperview()
previousViewController?.endAppearanceTransition()
previousViewController?.willMove(toParentViewController: nil)
previousViewController?.removeFromParentViewController()
addChildViewController(viewController)
view.addSubview(viewController.view)
view.sendSubview(toBack: viewController.view)
viewController.view.translatesAutoresizingMaskIntoConstraints = false
viewController.didMove(toParentViewController: self)
view.addConstraint(alignCenterXConstraint(forItem: viewController.view, toItem: centerViewController.view, position: position))
view.addConstraint(alignCenterYConstraint(forItem: viewController.view, toItem: centerViewController.view, position: position))
view.addConstraints(sizeConstraints(forItem: viewController.view, toItem: centerViewController.view))
}
func alignCenterXConstraint(forItem item: UIView, toItem: UIView, position: Position) -> NSLayoutConstraint {
let offset = position == .left ? -self.view.frame.width : position == .right ? toItem.frame.width : 0
return NSLayoutConstraint(item: item, attribute: .centerX, relatedBy: .equal, toItem: toItem, attribute: .centerX, multiplier: 1, constant: offset)
}
func alignCenterYConstraint(forItem item: UIView, toItem: UIView, position: Position) -> NSLayoutConstraint {
let offset = position == .top ? -self.view.frame.height : position == .bottom ? toItem.frame.height : 0
return NSLayoutConstraint(item: item, attribute: .centerY, relatedBy: .equal, toItem: toItem, attribute: .centerY, multiplier: 1, constant: offset)
}
func sizeConstraints(forItem item: UIView, toItem: UIView) -> [NSLayoutConstraint] {
let widthConstraint = NSLayoutConstraint(item: item, attribute: .width, relatedBy: .equal, toItem: toItem, attribute: .width, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: item, attribute: .height, relatedBy: .equal, toItem: toItem, attribute: .height, multiplier: 1, constant: 0)
return [widthConstraint, heightConstraint]
}
func hideButtons() {
UIView.animate(withDuration: 0.25) {
self.flipCameraButton.alpha = 0.0
}
}
func showButtons() {
UIView.animate(withDuration: 0.25) {
self.flipCameraButton.alpha = 1.0
}
}
func focusAnimationAt(_ point: CGPoint) {
let focusView = UIImageView(image: #imageLiteral(resourceName: "focus"))
focusView.center = point
focusView.alpha = 0.0
view.addSubview(focusView)
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
focusView.alpha = 1.0
focusView.transform = CGAffineTransform(scaleX: 1.25, y: 1.25)
}) { (success) in
UIView.animate(withDuration: 0.15, delay: 0.5, options: .curveEaseInOut, animations: {
focusView.alpha = 0.0
focusView.transform = CGAffineTransform(translationX: 0.6, y: 0.6)
}) { (success) in
focusView.removeFromSuperview()
}
}
}
func toggleFlashAnimation() {
if flashEnabled == true {
//flashButton.setImage(#imageLiteral(resourceName: "flash"), for: UIControlState())
} else {
//flashButton.setImage(#imageLiteral(resourceName: "flashOutline"), for: UIControlState())
}
}
}
CameraViewControler-
class CameraViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
UIApplication.shared.statusBarStyle = .lightContent
navigationController?.isNavigationBarHidden = true
}
}