// // CameraController.swift // CapFinder // // Created by User on 22.02.18. // Copyright © 2018 User. All rights reserved. // import UIKit protocol CameraControllerDelegate { func didCapture(image: UIImage) func didCancel() } class CameraController: UIViewController { private let imageSize = 299 // New for XCode models, 227/229 for turicreate // MARK: Outlets @IBOutlet weak var imageButton: RoundedButton! @IBOutlet weak var cropView: CropView! @IBOutlet weak var cancelButton: RoundedButton! @IBOutlet weak var cameraView: CameraView! { didSet { cameraView.configure() } } var delegate: CameraControllerDelegate? override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .portrait } override var shouldAutorotate: Bool { return false } // MARK: Actions @IBAction func backButtonPressed() { self.giveFeedback(.medium) delegate?.didCancel() self.dismiss(animated: true) } @IBAction func imageButtonPressed() { self.giveFeedback(.medium) imageButton.isEnabled = false cameraView.capture() } // MARK: Life cycle override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) cameraView.delegate = self imageButton.imageView?.image = UIImage.templateImage(named: "camera") setTintColor() cameraView.launch { success, error in guard let err = error else { return } switch err { case "No camera access": self.showNoCameraAccessAlert() case "Camera error": self.showAlert("Unable to capture media") default: self.showAlert("Error in camera setup") } } self.imageButton.isEnabled = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) cameraView.complete() } private func setTintColor() { let tint = AppDelegate.tintColor cropView.lineColor = tint imageButton.borderColor = tint imageButton.imageView?.tintColor = tint cancelButton.borderColor = tint cancelButton.set(template: "cancel", with: tint) } private func giveFeedback(_ style: UIImpactFeedbackGenerator.FeedbackStyle) { let generator = UIImpactFeedbackGenerator(style: style) generator.impactOccurred() } // MARK: Alerts private func showNoCameraAccessAlert() { let alert = UIAlertController(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.", preferredStyle: .alert, blurStyle: .dark) let okAction = UIAlertAction(title: "OK", style: .cancel, handler: nil) alert.addAction(okAction) let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { _ in // Take the user to Settings app to possibly change permission. guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } if UIApplication.shared.canOpenURL(settingsUrl) { UIApplication.shared.open(settingsUrl, completionHandler: nil) } }) alert.addAction(settingsAction) self.present(alert, animated: true, completion: nil) } override func touchesBegan(_ touches: Set, with event: UIEvent?) { cameraView.didReceiveTouch(touches.first!) } } extension CameraController: PhotoCaptureHandlerDelegate { func didCapture(_ image: UIImage?) { event("Image captured") let factor = CGFloat(cropView.relativeSize) self.dismiss(animated: true) let size = CGSize(width: imageSize, height: imageSize) guard let img = image else { self.error("No image captured") return } guard delegate != nil else { self.error("No delegate") return } guard let masked = img.crop(factor: factor).circleMasked else { self.error("Could not mask image") return } // Only use 227 x 227 image let scaled = masked.resize(to: size) delegate!.didCapture(image: scaled) } } extension CameraController: Logger { static var logToken = "[Camera]" }