Skip to content

Commit 0ca3e92

Browse files
committed
Add option to hide/show navigation bar
1 parent 4c06ae3 commit 0ca3e92

10 files changed

+458
-208
lines changed

Package.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ let package = Package(
2424
.target(
2525
name: "SwiftQRCodeScanner",
2626
dependencies: [],
27-
path: "Sources",
28-
exclude: ["Info.plist"]
27+
path: "Sources"
2928
),
3029
],
3130
swiftLanguageVersions: [.v5]

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ self.present(scanner, animated: true, completion: nil)
7575
```
7676
And finally implement delegate methods to get result:
7777
```Swift
78-
func qrScanner(_ controller: UIViewController, scanDidComplete result: String) {
78+
func qrScanner(_ controller: UIViewController, didScanQRCodeWithResult result: String) {
7979
print("result:\(result)")
8080
}
8181

82-
func qrScannerDidFail(_ controller: UIViewController, error: QRCodeError) {
82+
func qrScanner(_ controller: UIViewController, didFailWithError error: SwiftQRCodeScanner.QRCodeError) {
8383
print("error:\(error.localizedDescription)")
8484
}
8585

@@ -118,13 +118,13 @@ class ViewController: UIViewController {
118118

119119
}
120120

121-
extension ViewController: QRScannerCodeDelegate {
122-
func qrScannerDidFail(_ controller: UIViewController, error: QRCodeError) {
123-
print("error:\(error.localizedDescription)")
121+
extension ViewController: QRScannerCodeDelegate {
122+
func qrScanner(_ controller: UIViewController, didScanQRCodeWithResult result: String) {
123+
print("result:\(result)")
124124
}
125125

126-
func qrScanner(_ controller: UIViewController, scanDidComplete result: String) {
127-
print("result:\(result)")
126+
func qrScanner(_ controller: UIViewController, didFailWithError error: SwiftQRCodeScanner.QRCodeError) {
127+
print("error:\(error.localizedDescription)")
128128
}
129129

130130
func qrScannerDidCancel(_ controller: UIViewController) {
@@ -151,6 +151,7 @@ You can use following **QRScannerConfiguration** properties:
151151
| readQRFromPhotos | true | Hide/show "Upload From photos" button|
152152
| cancelButtonTitle | "Cancel" | Title for cancel button |
153153
| cancelButtonTintColor | nil | Color for cancel button |
154+
| hideNavigationBar| false | Hide/show navigation bar |
154155

155156
## Author
156157

Sources/SwiftQRCodeScanner/Configuration.swift

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import Foundation
1010
import UIKit
1111

1212
public struct QRScannerConfiguration {
13+
14+
// MARK: - Properties
15+
1316
public var title: String
1417
public var hint: String?
1518
public var invalidQRCodeAlertTitle: String
@@ -25,54 +28,52 @@ public struct QRScannerConfiguration {
2528
public var readQRFromPhotos: Bool
2629
public var cancelButtonTitle: String
2730
public var cancelButtonTintColor: UIColor?
31+
public var hideNavigationBar: Bool
32+
33+
// MARK: - Initializers
2834

2935
public init(title: String = "Scan QR Code",
30-
hint: String = "Align QR code within frame to scan",
36+
hint: String? = "Align QR code within frame to scan",
3137
uploadFromPhotosTitle: String = "Upload from photos",
3238
invalidQRCodeAlertTitle: String = "Invalid QR Code",
3339
invalidQRCodeAlertActionTitle: String = "OK",
3440
cameraImage: UIImage? = nil,
3541
flashOnImage: UIImage? = nil,
42+
galleryImage: UIImage? = nil,
3643
length: CGFloat = 20.0,
3744
color: UIColor = .green,
3845
radius: CGFloat = 10.0,
3946
thickness: CGFloat = 5.0,
4047
readQRFromPhotos: Bool = true,
4148
cancelButtonTitle: String = "Cancel",
42-
cancelButtonTintColor: UIColor? = nil) {
49+
cancelButtonTintColor: UIColor? = nil,
50+
hideNavigationBar: Bool = false) {
4351
self.title = title
4452
self.hint = hint
4553
self.uploadFromPhotosTitle = uploadFromPhotosTitle
4654
self.invalidQRCodeAlertTitle = invalidQRCodeAlertTitle
4755
self.invalidQRCodeAlertActionTitle = invalidQRCodeAlertActionTitle
4856
self.cameraImage = cameraImage
4957
self.flashOnImage = flashOnImage
58+
self.galleryImage = galleryImage
5059
self.length = length
5160
self.color = color
5261
self.radius = radius
5362
self.thickness = thickness
5463
self.readQRFromPhotos = readQRFromPhotos
5564
self.cancelButtonTitle = cancelButtonTitle
5665
self.cancelButtonTintColor = cancelButtonTintColor
66+
self.hideNavigationBar = hideNavigationBar
5767
}
5868
}
5969

70+
// MARK: - Default Configuration
71+
6072
extension QRScannerConfiguration {
6173
public static var `default`: QRScannerConfiguration {
62-
QRScannerConfiguration(title: "Scan QR Code",
63-
hint: "Align QR code within frame to scan",
64-
uploadFromPhotosTitle: "Upload from photos",
65-
invalidQRCodeAlertTitle: "Invalid QR Code",
66-
invalidQRCodeAlertActionTitle: "OK",
67-
cameraImage: nil,
68-
flashOnImage: nil,
69-
length: 20.0,
70-
color: .green,
71-
radius: 10.0,
72-
thickness: 5.0,
73-
readQRFromPhotos: true,
74-
cancelButtonTitle: "Cancel",
75-
cancelButtonTintColor: nil)
74+
.init()
7675
}
7776
}
77+
7878
#endif
79+

Sources/SwiftQRCodeScanner/ImagePicker.swift

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,45 @@ import Foundation
1010
import UIKit
1111
import PhotosUI
1212

13+
/// A protocol that defines the delegate method for handling the selected image.
1314
public protocol ImagePickerDelegate: AnyObject {
15+
/// Called when an image is selected from the image picker.
16+
///
17+
/// - Parameter image: The selected image, or nil if no image was selected.
1418
func didSelect(image: UIImage?)
1519
}
1620

17-
21+
/// A class that provides a system-provided interface for selecting an image from the camera roll or photo library.
1822
class PhotoPicker: NSObject {
1923

24+
// The image picker controller used to present the system interface.
2025
private let pickerController: UIImagePickerController
26+
27+
// A weak reference to the view controller that presents the image picker.
2128
private weak var presentationController: UIViewController?
29+
30+
// A weak reference to the delegate that will handle the selected image.
2231
private weak var delegate: ImagePickerDelegate?
2332

24-
public init(presentationController: UIViewController, delegate: ImagePickerDelegate) {
33+
/// Initializes a new instance of the `PhotoPicker` class.
34+
///
35+
/// - Parameters:
36+
/// - presentationController: The view controller that will present the image picker.
37+
/// - delegate: The delegate that will handle the selected image.
38+
public init(presentationController: UIViewController,
39+
delegate: ImagePickerDelegate) {
2540

2641
self.pickerController = UIImagePickerController()
2742
super.init()
2843
self.presentationController = presentationController
2944
self.delegate = delegate
3045
self.pickerController.delegate = self
3146
self.pickerController.allowsEditing = false
32-
3347
}
3448

49+
/// Presents the image picker interface from the specified source view.
50+
///
51+
/// - Parameter sourceView: The view from which the image picker should be presented.
3552
public func present(from sourceView: UIView) {
3653

3754
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
@@ -56,19 +73,29 @@ class PhotoPicker: NSObject {
5673
self.presentationController?.present(alertController, animated: true)
5774
}
5875

76+
// A private method that handles the selected image and notifies the delegate.
5977
private func pickerController(_ controller: UIImagePickerController, didSelect image: UIImage?) {
6078
controller.dismiss(animated: true, completion: nil)
6179
self.delegate?.didSelect(image: image)
6280
}
6381
}
6482

83+
// MARK: - UIImagePickerControllerDelegate
84+
6585
extension PhotoPicker: UIImagePickerControllerDelegate {
6686

87+
/// Called when the image picker is canceled.
88+
///
89+
/// - Parameter picker: The image picker controller that was canceled.
6790
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
68-
6991
picker.dismiss(animated: true)
7092
}
7193

94+
/// Called when an image has been selected from the image picker.
95+
///
96+
/// - Parameters:
97+
/// - picker: The image picker controller that selected the image.
98+
/// - info: A dictionary containing information about the selected media.
7299
public func imagePickerController(_ picker: UIImagePickerController,
73100
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
74101
guard let image = info[.originalImage] as? UIImage else {
@@ -78,17 +105,33 @@ extension PhotoPicker: UIImagePickerControllerDelegate {
78105
}
79106
}
80107

108+
// MARK: - UINavigationControllerDelegate
109+
81110
extension PhotoPicker: UINavigationControllerDelegate {}
82111

112+
// MARK: - PHPhotoPicker (Available on iOS 14 and later)
113+
83114
@available(iOS 14, *)
84-
extension PHPhotoPicker: UINavigationControllerDelegate{}
115+
extension PHPhotoPicker: UINavigationControllerDelegate {}
85116

117+
/// A class that provides an interface for selecting an image using the Photos UI on iOS 14 and later.
86118
@available(iOS 14, *)
87119
class PHPhotoPicker: NSObject {
120+
121+
// The Photos UI picker controller used to present the interface.
88122
private let pickerController: PHPickerViewController
123+
124+
// A weak reference to the view controller that presents the Photos UI picker.
89125
private weak var presentationController: UIViewController?
126+
127+
// A weak reference to the delegate that will handle the selected image.
90128
private weak var delegate: ImagePickerDelegate?
91129

130+
/// Initializes a new instance of the `PHPhotoPicker` class.
131+
///
132+
/// - Parameters:
133+
/// - presentationController: The view controller that will present the Photos UI picker.
134+
/// - delegate: The delegate that will handle the selected image.
92135
public init(presentationController: UIViewController, delegate: ImagePickerDelegate) {
93136
var phPickerConfiguration = PHPickerConfiguration(photoLibrary: .shared())
94137
phPickerConfiguration.selectionLimit = 1
@@ -100,26 +143,32 @@ class PHPhotoPicker: NSObject {
100143
self.delegate = delegate
101144
}
102145

146+
/// Requests authorization to access the photo library and presents the Photos UI picker if authorized.
103147
public func present() {
104-
PHPhotoLibrary.requestAuthorization({
105-
(newStatus) in
148+
PHPhotoLibrary.requestAuthorization({ (newStatus) in
106149
DispatchQueue.main.async {
107150
if newStatus == PHAuthorizationStatus.authorized {
108-
109-
self.presentationController?.present(self.pickerController, animated: true)
151+
self.presentationController?.present(self.pickerController,
152+
animated: true)
110153
}
111154
}
112155
})
113156
}
114-
115157
}
116158

159+
// MARK: - PHPickerViewControllerDelegate
160+
117161
@available(iOS 14, *)
118162
extension PHPhotoPicker: PHPickerViewControllerDelegate {
119163

120-
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
164+
/// Called when an image has been selected from the Photos UI picker.
165+
///
166+
/// - Parameters:
167+
/// - picker: The Photos UI picker controller that selected the image.
168+
/// - results: An array of `PHPickerResult` objects representing the selected images.
169+
func picker(_ picker: PHPickerViewController,
170+
didFinishPicking results: [PHPickerResult]) {
121171
picker.dismiss(animated: true, completion: nil)
122-
123172
for result in results {
124173
result.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
125174
if let image = object as? UIImage {
@@ -130,8 +179,6 @@ extension PHPhotoPicker: PHPickerViewControllerDelegate {
130179
})
131180
}
132181
}
133-
134182
}
135183

136184
#endif
137-

Sources/SwiftQRCodeScanner/QRCodeError.swift

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,25 @@
77

88
import Foundation
99

10-
public enum QRCodeError: Error {
10+
public enum QRCodeError: Error, Equatable {
1111
case inputFailed
12-
case outoutFailed
12+
case outputFailed
1313
case emptyResult
1414
}
1515

16-
extension QRCodeError: CustomStringConvertible {
17-
public var description: String {
16+
extension QRCodeError: CustomStringConvertible, LocalizedError {
17+
public var errorDescription: String? {
1818
switch self {
1919
case .inputFailed:
20-
return "Failed to add input."
21-
case .outoutFailed:
22-
return "Failed to add output."
20+
return NSLocalizedString("Failed to add input.", comment: "Failed to add input.")
21+
case .outputFailed:
22+
return NSLocalizedString("Failed to add output.", comment: "Failed to add output.")
2323
case .emptyResult:
24-
return "Empty string found."
24+
return NSLocalizedString("Empty string found", comment: "Empty string found.")
2525
}
2626
}
27-
}
2827

29-
extension QRCodeError: LocalizedError {
30-
public var errorDescription: String? {
31-
switch self {
32-
case .inputFailed:
33-
return NSLocalizedString(
34-
"Failed to add input.",
35-
comment: "Failed to add input."
36-
)
37-
case .outoutFailed:
38-
return NSLocalizedString(
39-
"Failed to add output.",
40-
comment: "Failed to add output."
41-
)
42-
case .emptyResult:
43-
return NSLocalizedString(
44-
"Empty string found.",
45-
comment: "Empty string found."
46-
)
47-
}
28+
public var description: String {
29+
return errorDescription ?? ""
4830
}
4931
}

Sources/SwiftQRCodeScanner/QRScannerFrame.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
// Created by Vinod Jagtap on 12/22/19.
66
//
77

8-
98
#if os(iOS)
109
import UIKit
1110

12-
1311
open class QRScannerFrame: UIView {
1412

1513
var length: CGFloat = 25.0 {
@@ -81,7 +79,6 @@ open class QRScannerFrame: UIView {
8179
path.lineWidth = thickness
8280
path.stroke()
8381
}
84-
8582
}
8683

8784
#endif

0 commit comments

Comments
 (0)