Skip to content

Commit 4245cca

Browse files
committed
Adding the preview layer example
1 parent f566d27 commit 4245cca

File tree

3 files changed

+111
-47
lines changed

3 files changed

+111
-47
lines changed

Example/QRCodeReader.swift.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@
557557
DEVELOPMENT_TEAM = "";
558558
INFOPLIST_FILE = QRCodeReader.swift/Info.plist;
559559
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
560-
PRODUCT_BUNDLE_IDENTIFIER = com.yannickloriot.qrcodereader;
560+
PRODUCT_BUNDLE_IDENTIFIER = com.workandplay.qrcodereader;
561561
PRODUCT_NAME = "$(TARGET_NAME)";
562562
SWIFT_VERSION = 3.0;
563563
};
@@ -572,7 +572,7 @@
572572
DEVELOPMENT_TEAM = "";
573573
INFOPLIST_FILE = QRCodeReader.swift/Info.plist;
574574
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
575-
PRODUCT_BUNDLE_IDENTIFIER = com.yannickloriot.qrcodereader;
575+
PRODUCT_BUNDLE_IDENTIFIER = com.workandplay.qrcodereader;
576576
PRODUCT_NAME = "$(TARGET_NAME)";
577577
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
578578
SWIFT_VERSION = 3.0;
Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3+
<device id="retina4_7" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
36
<dependencies>
47
<deployment identifier="iOS"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
9+
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
610
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
711
</dependencies>
812
<scenes>
@@ -18,38 +22,70 @@
1822
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
1923
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
2024
<subviews>
21-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P5n-CT-PTt">
25+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MLx-jM-72O">
26+
<rect key="frame" x="27.5" y="258" width="320" height="150"/>
27+
<subviews>
28+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P5n-CT-PTt">
29+
<rect key="frame" x="0.0" y="0.0" width="150" height="150"/>
30+
<constraints>
31+
<constraint firstAttribute="width" secondItem="P5n-CT-PTt" secondAttribute="height" multiplier="1:1" id="caB-yF-0Tz"/>
32+
</constraints>
33+
<state key="normal" title="Scan In Modal">
34+
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
35+
</state>
36+
<connections>
37+
<action selector="scanInModalAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="ipn-cc-fV7"/>
38+
</connections>
39+
</button>
40+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GEY-6q-XoF">
41+
<rect key="frame" x="170" y="0.0" width="150" height="150"/>
42+
<constraints>
43+
<constraint firstAttribute="width" secondItem="GEY-6q-XoF" secondAttribute="height" multiplier="1:1" id="aNx-Af-OB1"/>
44+
</constraints>
45+
<state key="normal" title="Scan In Preview">
46+
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
47+
</state>
48+
<connections>
49+
<action selector="scanInPreviewAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="87h-CK-v4h"/>
50+
</connections>
51+
</button>
52+
</subviews>
53+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
2254
<constraints>
23-
<constraint firstAttribute="width" constant="155" id="O9u-YB-D6M"/>
24-
<constraint firstAttribute="height" constant="150" id="h6v-qf-cpj"/>
55+
<constraint firstAttribute="width" constant="320" id="0tw-at-1eY"/>
56+
<constraint firstAttribute="bottom" secondItem="GEY-6q-XoF" secondAttribute="bottom" id="7pw-9h-iOI"/>
57+
<constraint firstAttribute="height" constant="150" id="D8n-7o-jZH"/>
58+
<constraint firstAttribute="bottom" secondItem="P5n-CT-PTt" secondAttribute="bottom" id="DmC-bG-M6d"/>
59+
<constraint firstItem="P5n-CT-PTt" firstAttribute="leading" secondItem="MLx-jM-72O" secondAttribute="leading" id="HbM-1L-ys2"/>
60+
<constraint firstItem="GEY-6q-XoF" firstAttribute="top" secondItem="MLx-jM-72O" secondAttribute="top" id="LVD-tP-cMN"/>
61+
<constraint firstItem="P5n-CT-PTt" firstAttribute="top" secondItem="MLx-jM-72O" secondAttribute="top" id="MSC-L6-cFy"/>
62+
<constraint firstAttribute="trailing" secondItem="GEY-6q-XoF" secondAttribute="trailing" id="qAj-Jo-ucp"/>
2563
</constraints>
26-
<state key="normal" title="Scan">
27-
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
28-
</state>
29-
<connections>
30-
<action selector="scanAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Tum-8Y-xC0"/>
31-
</connections>
32-
</button>
33-
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="B2g-a5-1sz">
64+
</view>
65+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ROG-L6-Gnz">
66+
<rect key="frame" x="87" y="42" width="200" height="200"/>
3467
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
3568
<constraints>
36-
<constraint firstAttribute="width" constant="250" id="VMR-rE-WTj"/>
37-
<constraint firstAttribute="height" constant="40" id="px8-Qg-UCc"/>
69+
<constraint firstAttribute="width" secondItem="ROG-L6-Gnz" secondAttribute="height" multiplier="1:1" id="5Br-7H-vZp"/>
70+
<constraint firstAttribute="height" constant="200" id="m30-Dq-t2L"/>
3871
</constraints>
3972
</view>
4073
</subviews>
4174
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
4275
<constraints>
43-
<constraint firstItem="B2g-a5-1sz" firstAttribute="top" secondItem="P5n-CT-PTt" secondAttribute="bottom" constant="-4" id="17H-xA-CBR"/>
44-
<constraint firstAttribute="centerX" secondItem="P5n-CT-PTt" secondAttribute="centerX" constant="0.5" id="CeZ-ED-sHl"/>
45-
<constraint firstItem="B2g-a5-1sz" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="Uaw-ng-H0t"/>
46-
<constraint firstAttribute="centerY" secondItem="P5n-CT-PTt" secondAttribute="centerY" id="fM5-Fa-KlF"/>
76+
<constraint firstItem="MLx-jM-72O" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="TFI-BI-W1n"/>
77+
<constraint firstItem="ROG-L6-Gnz" firstAttribute="centerX" secondItem="MLx-jM-72O" secondAttribute="centerX" id="UgF-Hf-Eb1"/>
78+
<constraint firstItem="MLx-jM-72O" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="efo-xp-hOO"/>
79+
<constraint firstItem="MLx-jM-72O" firstAttribute="top" secondItem="ROG-L6-Gnz" secondAttribute="bottom" constant="16" id="mfA-gu-dvY"/>
4780
</constraints>
4881
</view>
82+
<connections>
83+
<outlet property="previewView" destination="ROG-L6-Gnz" id="AnF-TH-j7l"/>
84+
</connections>
4985
</viewController>
5086
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
5187
</objects>
52-
<point key="canvasLocation" x="305" y="429"/>
88+
<point key="canvasLocation" x="304.80000000000001" y="428.63568215892059"/>
5389
</scene>
5490
</scenes>
5591
</document>

Example/QRCodeReader.swift/ViewController.swift

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
*
2525
*/
2626

27-
import UIKit
2827
import AVFoundation
28+
import UIKit
2929

3030
class ViewController: UIViewController, QRCodeReaderViewControllerDelegate {
31-
lazy var reader: QRCodeReaderViewController = {
31+
@IBOutlet weak var previewView: UIView!
32+
lazy var reader: QRCodeReader = QRCodeReader()
33+
lazy var readerVC: QRCodeReaderViewController = {
3234
let builder = QRCodeReaderViewControllerBuilder {
3335
$0.reader = QRCodeReader(metadataObjectTypes: [AVMetadataObjectTypeQRCode], captureDevicePosition: .back)
3436
$0.showTorchButton = true
@@ -37,46 +39,72 @@ class ViewController: UIViewController, QRCodeReaderViewControllerDelegate {
3739
return QRCodeReaderViewController(builder: builder)
3840
}()
3941

40-
@IBAction func scanAction(_ sender: AnyObject) {
41-
do {
42-
if try QRCodeReader.supportsMetadataObjectTypes() {
43-
reader.modalPresentationStyle = .formSheet
44-
reader.delegate = self
42+
// MARK: - Actions
4543

46-
reader.completionBlock = { (result: QRCodeReaderResult?) in
47-
if let result = result {
48-
print("Completion with result: \(result.value) of type \(result.metadataType)")
49-
}
50-
}
51-
52-
present(reader, animated: true, completion: nil)
53-
}
44+
private func checkScanPermissions() -> Bool {
45+
do {
46+
return try QRCodeReader.supportsMetadataObjectTypes()
5447
} catch let error as NSError {
48+
let alert: UIAlertController?
49+
5550
switch error.code {
5651
case -11852:
57-
let alert = UIAlertController(title: "Error", message: "This app is not authorized to use Back Camera.", preferredStyle: .alert)
52+
alert = UIAlertController(title: "Error", message: "This app is not authorized to use Back Camera.", preferredStyle: .alert)
5853

59-
alert.addAction(UIAlertAction(title: "Setting", style: .default, handler: { (_) in
54+
alert?.addAction(UIAlertAction(title: "Setting", style: .default, handler: { (_) in
6055
DispatchQueue.main.async {
6156
if let settingsURL = URL(string: UIApplicationOpenSettingsURLString) {
6257
UIApplication.shared.openURL(settingsURL)
6358
}
6459
}
6560
}))
66-
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
67-
present(alert, animated: true, completion: nil)
6861

62+
alert?.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
63+
case -11814:
64+
alert = UIAlertController(title: "Error", message: "Reader not supported by the current device", preferredStyle: .alert)
65+
alert?.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
66+
default:
67+
alert = nil
68+
}
6969

70+
guard let vc = alert else { return false }
7071

71-
case -11814:
72-
let alert = UIAlertController(title: "Error", message: "Reader not supported by the current device", preferredStyle: .alert)
73-
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
72+
present(vc, animated: true, completion: nil)
73+
74+
return false
75+
}
76+
}
7477

75-
present(alert, animated: true, completion: nil)
76-
default:()
78+
@IBAction func scanInModalAction(_ sender: AnyObject) {
79+
guard checkScanPermissions() else { return }
80+
81+
readerVC.modalPresentationStyle = .formSheet
82+
readerVC.delegate = self
83+
84+
readerVC.completionBlock = { (result: QRCodeReaderResult?) in
85+
if let result = result {
86+
print("Completion with result: \(result.value) of type \(result.metadataType)")
7787
}
7888
}
7989

90+
present(readerVC, animated: true, completion: nil)
91+
}
92+
93+
@IBAction func scanInPreviewAction(_ sender: Any) {
94+
guard checkScanPermissions(), !reader.isRunning else { return }
95+
96+
reader.previewLayer.frame = previewView.bounds
97+
previewView.layer.addSublayer(reader.previewLayer)
98+
99+
reader.startScanning()
100+
reader.didFindCode = { result in
101+
let alert = UIAlertController(
102+
title: "QRCodeReader",
103+
message: String (format:"%@ (of type %@)", result.value, result.metadataType),
104+
preferredStyle: .alert
105+
)
106+
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
107+
}
80108
}
81109

82110
// MARK: - QRCodeReader Delegate Methods

0 commit comments

Comments
 (0)