Create fully customisable camera view in no time. Keep your code clean
Try demo we prepared | Roadmap | Propose a new feature
CameraView by Mijick is a powerful, open-source library that simplifies the camera presentation process, making it super fast and totally customisable, allowing you to focus on the important elements of your project while hiding the technical complexities.
- Customise your UI completely. Use a clean and modern UI we designed or change it completely within minutes!
- Covers the entire process. Our library both presents the camera controller, asks for permissions, displays an error view if permissions are not granted, and shows the result of the capture in a separate view (if you wish, of course).
- Improves code quality. Allows you to focus on the most important things, hiding implementation details inside this powerful library.
- Designed for SwiftUI. As we developed the library, we utilized SwiftUI's capabilities to offer you a powerful tool for streamlining your implementation process.
Platforms | Minimum Swift Version |
---|---|
iOS 14+ | 5.10 |
Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the Swift compiler.
Once you have your Swift package set up, adding CameraView as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/Mijick/CameraView.git", branch(“main”))
]
Cocoapods is a dependency manager for Swift and Objective-C Cocoa projects that helps to scale them elegantly.
Installation steps:
- Install CocoaPods 1.10.0 (or later)
- Generate CocoaPods for your project
pod init
- Add CocoaPods dependency into your
Podfile
pod 'MijickCameraView'
- Install dependency and generate
.xcworkspace
file
pod install
- Use new XCode project file
.xcworkspace
Open the info.plist file of your project. Add two new keys: Privacy - Microphone Usage Description
and Privacy - Camera Usage Description
. Value will be displayed by default in the error screen when the user denies access to one of the above permissions.
Create a camera manager object in the view structure to contain MCameraController. It can be initialized with attributes, with which you will start an instance of your camera.
struct CameraView: View {
@ObservedObject private var manager: CameraManager = .init(
outputType: .photo,
cameraPosition: .back,
cameraFilters: [.init(name: "CISepiaTone")!],
resolution: .hd4K3840x2160,
frameRate: 25,
flashMode: .off,
isGridVisible: true,
focusImageColor: .yellow,
focusImageSize: 92
)
(...)
var body: some View {
(...)
}
(...)
}
MCameraController contains three screens - CameraView
, CameraPreview
(which can be turned off) and CameraErrorView
. Therefore, we advise that there should be no other elements in the view where you declare MCameraController
. We’ve designed this system around the experience and needs of ourselves and the developers we know. However, if your preferences are different, we are happy to meet your expectations and adapt our library. Share them with us by creating an issue for this project.
struct CameraView: View {
@ObservedObject private var manager: CameraManager = (...)
(...)
var body: some View {
MCameraController(manager: manager)
}
(...)
}
The above functions define what happens after a given action and are optional; for example, if your application only captures images, you don't need to declare onVideoCaptured and so on.
struct CameraView: View {
(...)
var body: some View {
MCameraController(manager: manager)
.onImageCaptured { data in
print("IMAGE CAPTURED")
}
.onVideoCaptured { url in
print("VIDEO CAPTURED")
}
.afterMediaCaptured { $0
.closeCameraController(true)
.custom { print("Media object has been successfully captured") }
}
.onCloseController {
print("CLOSE THE CONTROLLER")
}
}
(...)
}
CameraView library by Mijick, allows you to lock the screen rotation for MCameraController
, even if a device rotation is unlocked.
To achieve it, create an AppDelegate class conforming to MApplicationDelegate
, declare @UIApplicationDelegateAdaptor
in @main struct
and set lockOrientation(AppDelegate.self)
for MCameraController
.
class AppDelegate: NSObject, MApplicationDelegate {
static var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { AppDelegate.orientationLock }
}
@main struct CameraView_DemoApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup(content: CameraView.init)
}
}
struct CameraView: View {
(...)
var body: some View {
MCameraController(manager: manager)
.lockOrientation(AppDelegate.self)
}
(...)
}
You can change the appearance of the CameraView
by creating a new structure, conforming to MCameraView
and using the cameraScreen
modifier.
struct CustomCameraView: MCameraView {
@ObservedObject var cameraManager: MijickCameraView.CameraManager
let namespace: Namespace.ID
let closeControllerAction: () -> ()
var body: some View {
VStack(spacing: 0) {
createNavigationBar()
createCameraView()
createCaptureButton()
}
}
}
private extension CustomCameraView {
func createNavigationBar() -> some View {
Text("This is a Custom Camera View")
.padding(.top, 12)
.padding(.bottom, 12)
}
func createCaptureButton() -> some View {
Button(action: captureOutput) { Text("Click to capture") }
.padding(.top, 12)
.padding(.bottom, 12)
}
}
struct CameraView: View {
(...)
var body: some View {
MCameraController(manager: manager)
.cameraScreen(CustomCameraView.init)
}
(...)
}
You can change the appearance of the CameraPreview
by creating a new structure, conforming to MCameraPreview
and using the mediaPreviewScreen
modifier.
Note: To disable the preview of captured media, use the mediaPreviewScreen modifier with nil as the argument.
struct CustomCameraPreview: MCameraPreview {
let capturedMedia: MijickCameraView.MCameraMedia
let namespace: Namespace.ID
let retakeAction: () -> ()
let acceptMediaAction: () -> ()
var body: some View {
VStack(spacing: 0) {
Spacer()
createContentView()
Spacer()
createButtons()
}
}
}
private extension CustomCameraPreview {
func createContentView() -> some View { ZStack {
if let image = capturedMedia.image { createImageView(image) }
else { EmptyView() }
}}
func createButtons() -> some View {
HStack(spacing: 24) {
createRetakeButton()
createSaveButton()
}
}
}
private extension CustomCameraPreview {
func createImageView(_ image: Data) -> some View {
Image(uiImage: .init(data: image) ?? .init())
.resizable()
.aspectRatio(contentMode: .fit)
.ignoresSafeArea()
}
func createRetakeButton() -> some View {
Button(action: retakeAction) { Text("Retake") }
}
func createSaveButton() -> some View {
Button(action: acceptMediaAction) { Text("Save") }
}
}
struct CameraView: View {
(...)
var body: some View {
MCameraController(manager: manager)
.mediaPreviewScreen(CustomCameraPreview.init)
}
(...)
}
You can change the appearance of the CameraErrorView
by creating a new structure, conforming to MCameraErrorView
and using the errorScreen
modifier.
struct CustomCameraErrorView: MCameraErrorView {
let error: CameraManager.Error
let closeControllerAction: () -> ()
var body: some View {
Button(action: openAppSettings) { Text("Open Settings") }
}
}
struct CameraView: View {
(...)
var body: some View {
MCameraController(manager: manager)
.errorScreen(CustomCameraErrorView.init)
}
(...)
}
See for yourself how does it work by cloning project we created
CameraView is released under the MIT license. See LICENSE for details.
PopupView - The most powerful popup library that allows you to present any popup
NavigationView - Easier and cleaner way of navigating through your app
CalendarView - Create your own calendar object in no time
GridView - Lay out your data with no effort
Timer - Modern API for Timer