MijickCamera/Sources/Public/Camera Settings/Public+CameraSettings+MCamera.swift

406 lines
14 KiB
Swift
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Public+CameraSettings+MCamera.swift of MijickCamera
//
// Created by Tomasz Kurylik. Sending from Kraków!
// - Mail: tomasz.kurylik@mijick.com
// - GitHub: https://github.com/FulcrumOne
// - Medium: https://medium.com/@mijick
//
// Copyright ©2024 Mijick. All rights reserved.
import SwiftUI
import AVKit
// MARK: Initializer
public extension MCamera {
init() { self.init(manager: .init(
captureSession: AVCaptureSession(),
captureDeviceInputType: AVCaptureDeviceInput.self
))}
}
// MARK: - METHODS
// MARK: Changing Default Screens
public extension MCamera {
/**
Changes the camera screen to a selected one.
For more details and tips on creating your own **Camera Screen**, see the ``MCameraScreen`` documentation.
- tip: To hide selected buttons and controls on the screen, use the method with DefaultCameraScreen as argument. For a code example, please refer to Usage -> Default Camera Screen Customization section.
# Usage
## New Camera Screen
```swift
struct ContentView: View {
var body: some View {
MCamera()
.setCameraScreen(CustomCameraScreen.init)
// MUST BE CALLED!
.startSession()
}
}
```
## Default Camera Screen Customization
```swift
struct ContentView: View {
var body: some View {
MCamera()
.setCameraScreen {
DefaultCameraScreen(cameraManager: $0, namespace: $1, closeMCameraAction: $2)
.captureButtonAllowed(false)
.cameraOutputSwitchAllowed(false)
.lightButtonAllowed(false)
}
// MUST BE CALLED!
.startSession()
}
}
```
*/
func setCameraScreen(_ builder: @escaping CameraScreenBuilder) -> Self { config.cameraScreen = builder; return self }
/**
Changes the captured media screen to a selected one.
For more details and tips on creating your own **Captured Media Screen**, see the ``MCapturedMediaScreen`` documentation.
- tip: To disable displaying captured media, call the method with a nil value.
# Usage
## New Captured Media Screen
```swift
struct ContentView: View {
var body: some View {
MCamera()
.setCapturedMediaScreen(DefaultCapturedMediaScreen.init)
// MUST BE CALLED!
.startSession()
}
}
```
## No Captured Media Screen
```swift
struct ContentView: View {
var body: some View {
MCamera()
.setCapturedMediaScreen(nil)
// MUST BE CALLED!
.startSession()
}
}
```
*/
func setCapturedMediaScreen(_ builder: CapturedMediaScreenBuilder?) -> Self { config.capturedMediaScreen = builder; return self }
/**
Changes the error screen to a selected one.
For more details and tips on creating your own **Error Screen**, see the ``MCameraErrorScreen`` documentation.
## Usage
```swift
struct ContentView: View {
var body: some View {
MCamera()
.setErrorScreen(CustomCameraErrorScreen.init)
// MUST BE CALLED!
.startSession()
}
}
```
*/
func setErrorScreen(_ builder: @escaping ErrorScreenBuilder) -> Self { config.errorScreen = builder; return self }
}
// MARK: Changing Initial Values
public extension MCamera {
/**
Changes the initial camera output type.
For available options, please refer to the ``CameraOutputType`` documentation.
*/
func setCameraOutputType(_ cameraOutputType: CameraOutputType) -> Self { manager.attributes.outputType = cameraOutputType; return self }
/**
Changes the initial camera position.
For available options, please refer to the ``CameraPosition`` documentation.
- note: If the selected camera position is not available, the camera will not be changed.
*/
func setCameraPosition(_ cameraPosition: CameraPosition) -> Self { manager.attributes.cameraPosition = cameraPosition; return self }
/**
Definies whether the audio source is available.
If disabled, the camera will not record audio, and will not ask for permission to access the microphone.
*/
func setAudioAvailability(_ isAvailable: Bool) -> Self { manager.attributes.isAudioSourceAvailable = isAvailable; return self }
/**
Changes the initial camera zoom level.
- note: If the zoom factor is out of bounds, it will be set to the closest available value.
*/
func setZoomFactor(_ zoomFactor: CGFloat) -> Self { manager.attributes.zoomFactor = zoomFactor; return self }
/**
Changes the initial camera flash mode.
For available options, please refer to the ``CameraFlashMode`` documentation.
- note: If the selected flash mode is not available, the flash mode will not be changed.
*/
func setFlashMode(_ flashMode: CameraFlashMode) -> Self { manager.attributes.flashMode = flashMode; return self }
/**
Sets the screen flash color for front camera captures.
When taking photos with the front camera with flash enabled, the screen will illuminate
with this color to light up the subject's face. If not set, defaults to white.
- parameter color: The UIColor to use for screen flash illumination.
*/
func setScreenFlashColor(_ color: UIColor?) -> Self { manager.attributes.screenFlashColor = color; return self }
/**
Changes the initial light (torch / flashlight) mode.
For available options, please refer to the ``CameraLightMode`` documentation.
- note: If the selected light mode is not available, the light mode will not be changed.
*/
func setLightMode(_ lightMode: CameraLightMode) -> Self { manager.attributes.lightMode = lightMode; return self }
/**
Changes the initial camera resolution.
- important: Changing the resolution may affect the maximum frame rate that can be set.
*/
func setResolution(_ resolution: AVCaptureSession.Preset) -> Self { manager.attributes.resolution = resolution; return self }
/**
Changes the initial camera frame rate.
- note: Depending on the resolution of the camera and the current specifications of the device, there are some restrictions on the frame rate that can be set.
If you set a frame rate that exceeds the camera's capabilities, the library will automatically set the closest possible value and show you which value has been set (``MCameraScreen/frameRate``).
*/
func setFrameRate(_ frameRate: Int32) -> Self { manager.attributes.frameRate = frameRate; return self }
/**
Changes the initial camera exposure duration.
- note: If the exposure duration is out of bounds, it will be set to the closest available value.
*/
func setCameraExposureDuration(_ duration: CMTime) -> Self { manager.attributes.cameraExposure.duration = duration; return self }
/**
Changes the initial camera target bias.
- note: If the target bias is out of bounds, it will be set to the closest available value.
*/
func setCameraTargetBias(_ targetBias: Float) -> Self { manager.attributes.cameraExposure.targetBias = targetBias; return self }
/**
Changes the initial camera ISO.
- note: If the ISO is out of bounds, it will be set to the closest available value.
*/
func setCameraISO(_ iso: Float) -> Self { manager.attributes.cameraExposure.iso = iso; return self }
/**
Changes the initial camera exposure mode.
- note: If the exposure mode is not supported, the exposure mode will not be changed.
*/
func setCameraExposureMode(_ exposureMode: AVCaptureDevice.ExposureMode) -> Self { manager.attributes.cameraExposure.mode = exposureMode; return self }
/**
Changes the initial camera HDR mode.
For available options, please refer to the ``CameraHDRMode`` documentation.
*/
func setCameraHDRMode(_ hdrMode: CameraHDRMode) -> Self { manager.attributes.hdrMode = hdrMode; return self }
/**
Changes the initial camera filters.
- important: Setting multiple filters simultaneously can affect the performance of the camera.
*/
func setCameraFilters(_ filters: [CIFilter]) -> Self { manager.attributes.cameraFilters = filters; return self }
/**
Changes the initial mirror output setting.
*/
func setMirrorOutput(_ shouldMirror: Bool) -> Self { manager.attributes.mirrorOutput = shouldMirror; return self }
/**
Changes the initial grid visibility setting.
*/
func setGridVisibility(_ shouldShowGrid: Bool) -> Self { manager.attributes.isGridVisible = shouldShowGrid; return self }
/**
Changes the shape of the focus indicator visible when touching anywhere on the camera screen.
*/
func setFocusImage(_ image: UIImage) -> Self { manager.cameraMetalView.focusIndicator.image = image; return self }
/**
Changes the color of the focus indicator visible when touching anywhere on the camera screen.
*/
func setFocusImageColor(_ color: UIColor) -> Self { manager.cameraMetalView.focusIndicator.tintColor = color; return self }
/**
Changes the size of the focus indicator visible when touching anywhere on the camera.
*/
func setFocusImageSize(_ size: CGFloat) -> Self { manager.cameraMetalView.focusIndicator.size = size; return self }
}
// MARK: Actions
public extension MCamera {
/**
Indicates how the MCamera can be closed.
## Usage
```swift
struct ContentView: View {
@State private var isSheetPresented: Bool = false
var body: some View {
Button(action: { isSheetPresented = true }) {
Text("Click me!")
}
.fullScreenCover(isPresented: $isSheetPresented) {
MCamera()
.setResolution(.hd1920x1080)
.setCloseMCameraAction { isSheetPresented = false }
// MUST BE CALLED!
.startSession()
}
}
}
```
*/
func setCloseMCameraAction(_ action: @escaping () -> ()) -> Self { config.closeMCameraAction = action; return self }
/**
Defines action that is called when an image is captured.
MCameraController can be used to perform additional actions related to MCamera, such as closing MCamera or returning to the camera screen.
See ``Controller`` for more information.
- note: The action is called immediately if **Captured Media Screen** is nil, otherwise after the user accepts the photo.
## Usage
```swift
struct ContentView: View {
var body: some View {
MCamera()
.onImageCaptured { image, controller in
saveImageInGallery(image)
controller.reopenCameraScreen()
}
// MUST BE CALLED!
.startSession()
}
}
```
*/
func onImageCaptured(_ action: @escaping (UIImage, MCamera.Controller) -> ()) -> Self { config.imageCapturedAction = action; return self }
/**
Defines action that is called when a video is captured.
MCameraController can be used to perform additional actions related to MCamera, such as closing MCamera or returning to the camera screen.
See ``Controller`` for more information.
- note: The action is called immediately if **Captured Media Screen** is nil, otherwise after the user accepts the video.
## Usage
```swift
struct ContentView: View {
var body: some View {
MCamera()
.onVideoCaptured { video, controller in
saveVideoInGallery(video)
controller.reopenCameraScreen()
}
// MUST BE CALLED!
.startSession()
}
}
```
*/
func onVideoCaptured(_ action: @escaping (URL, MCamera.Controller) -> ()) -> Self { config.videoCapturedAction = action; return self }
}
// MARK: Others
public extension MCamera {
/**
Locks the screen in portrait mode when the Camera Screen is active.
See ``MApplicationDelegate`` for more details.
- note: Blocks the rotation of the entire screen on which the **MCamera** is located.
## Usage
```swift
@main struct App_Main: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup(content: ContentView.init)
}
}
// MARK: App Delegate
class AppDelegate: NSObject, MApplicationDelegate {
static var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { AppDelegate.orientationLock }
}
// MARK: Content View
struct ContentView: View {
var body: some View {
MCamera()
.lockCameraInPortraitOrientation(AppDelegate.self)
// MUST BE CALLED!
.startSession()
}
}
```
*/
func lockCameraInPortraitOrientation(_ appDelegate: MApplicationDelegate.Type) -> Self { config.appDelegate = appDelegate; manager.attributes.orientationLocked = true; return self }
/**
Starts the camera session.
- important: This method must be called to start the camera.
*/
func startSession() -> some View { config.isCameraConfigured = true; return self }
}