Merge swift3 branch

This commit is contained in:
Yannick Loriot 2016-09-13 23:51:56 +02:00
commit b8f0313283
19 changed files with 613 additions and 269 deletions

View File

@ -1,19 +1,35 @@
# Change log
## [Version 7.0.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/7.0.0)
Released on 2016-09-13.
**Swift 3 supports**
- [REFACTORING] Use `QRCodeReaderViewControllerBuilder` instead of `QRCodeViewControllerBuilder`
- [REFACTORING] Remove all deprecated apis
- [ADD] Swift Package Manager supports
`QRCodeReader`:
- Use `didFindCode` instead of `didFindCodeBlock`
- Use `isRunning` instead of `running`
- Use `videoOrientation` instead of `videoOrientationFromDeviceOrientation`
- `hasFrontDevice` is a property
- `isTorchAvailable` is a property
## [Version 6.2.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/6.2.0)
Released on 2016-09-08.
- Deprecating all initializers expect `initWithBuilder` in order to remove them in the next version
- [REFACTORING] Deprecating all initializers expect `initWithBuilder` in order to remove them in the next version
## [Version 6.1.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/6.1.0)
Released on 2016-08-03.
- Hide/Display cancel button
- [ADD] Hide/Display cancel button
## [Version 6.0.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/6.0.0)
Released on 2016-03-22.
- Swift 2.2 supports
**Swift 2.2 supports**
## [Version 5.4.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/5.4.0)
Released on 2016-03-14.
@ -58,7 +74,8 @@ Released on 2015-10-06.
## [Version 5.0.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/5.0.0)
Released on 2015-09-17.
- [REFACTORING] Switch to Swift 2
**Swift 2 supports**
- [ADD] Carthage supports
## [Version 4.3.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/4.3.0)
@ -81,7 +98,7 @@ Released on 2015-04-15.
## [Version 4.0.0](https://github.com/yannickl/QRCodeReader.swift/releases/tag/4.0.0)
Released on 2015-04-11.
- [REFACTORING] Swift 1.2 support
**Swift 1.2 supports**
## [Version 3.1.8](https://github.com/yannickl/QRCodeReader.swift/releases/tag/3.1.8)
Released on 2015-03-28.

View File

@ -7,30 +7,36 @@
objects = {
/* Begin PBXBuildFile section */
4A0723DC1C223D8100F2C410 /* QRCodeReaderResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A0723DB1C223D8100F2C410 /* QRCodeReaderResult.swift */; };
4A0723DD1C22405100F2C410 /* QRCodeReaderResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A0723DB1C223D8100F2C410 /* QRCodeReaderResult.swift */; };
82BD4A0A1BBC21F800172E4E /* ToggleTorchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82BD4A091BBC21F800172E4E /* ToggleTorchButton.swift */; };
82D83BA71BBC2A3100C94C22 /* ToggleTorchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82BD4A091BBC21F800172E4E /* ToggleTorchButton.swift */; };
CE345B231C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE345B221C444D6400FCC482 /* QRCodeViewControllerBuilder.swift */; };
CE345B241C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE345B221C444D6400FCC482 /* QRCodeViewControllerBuilder.swift */; };
CE345B251C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE345B221C444D6400FCC482 /* QRCodeViewControllerBuilder.swift */; };
CE412E8F19D9A1E4000F294E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE412E8E19D9A1E4000F294E /* AppDelegate.swift */; };
CE412E9119D9A1E4000F294E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE412E9019D9A1E4000F294E /* ViewController.swift */; };
CE412E9419D9A1E4000F294E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE412E9219D9A1E4000F294E /* Main.storyboard */; };
CE412E9619D9A1E4000F294E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE412E9519D9A1E4000F294E /* Images.xcassets */; };
CE412E9919D9A1E4000F294E /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE412E9719D9A1E4000F294E /* LaunchScreen.xib */; };
CE412EA519D9A1E4000F294E /* QRCodeReader_swiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE412EA419D9A1E4000F294E /* QRCodeReader_swiftTests.swift */; };
CE4E1EDA1D81838F00D2AC35 /* QRCodeReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED31D81838F00D2AC35 /* QRCodeReader.swift */; };
CE4E1EDB1D81838F00D2AC35 /* QRCodeReaderResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED41D81838F00D2AC35 /* QRCodeReaderResult.swift */; };
CE4E1EDC1D81838F00D2AC35 /* QRCodeReaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED51D81838F00D2AC35 /* QRCodeReaderViewController.swift */; };
CE4E1EDD1D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED61D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift */; };
CE4E1EDE1D81838F00D2AC35 /* ReaderOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED71D81838F00D2AC35 /* ReaderOverlayView.swift */; };
CE4E1EDF1D81838F00D2AC35 /* SwitchCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED81D81838F00D2AC35 /* SwitchCameraButton.swift */; };
CE4E1EE01D81838F00D2AC35 /* ToggleTorchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED91D81838F00D2AC35 /* ToggleTorchButton.swift */; };
CE4E1EE11D81839D00D2AC35 /* QRCodeReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED31D81838F00D2AC35 /* QRCodeReader.swift */; };
CE4E1EE21D81839D00D2AC35 /* QRCodeReaderResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED41D81838F00D2AC35 /* QRCodeReaderResult.swift */; };
CE4E1EE31D81839D00D2AC35 /* QRCodeReaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED51D81838F00D2AC35 /* QRCodeReaderViewController.swift */; };
CE4E1EE41D81839D00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED61D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift */; };
CE4E1EE51D81839D00D2AC35 /* ReaderOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED71D81838F00D2AC35 /* ReaderOverlayView.swift */; };
CE4E1EE61D81839D00D2AC35 /* SwitchCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED81D81838F00D2AC35 /* SwitchCameraButton.swift */; };
CE4E1EE71D81839D00D2AC35 /* ToggleTorchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED91D81838F00D2AC35 /* ToggleTorchButton.swift */; };
CE4E1EE81D81839D00D2AC35 /* QRCodeReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED31D81838F00D2AC35 /* QRCodeReader.swift */; };
CE4E1EE91D81839D00D2AC35 /* QRCodeReaderResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED41D81838F00D2AC35 /* QRCodeReaderResult.swift */; };
CE4E1EEA1D81839D00D2AC35 /* QRCodeReaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED51D81838F00D2AC35 /* QRCodeReaderViewController.swift */; };
CE4E1EEB1D81839D00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED61D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift */; };
CE4E1EEC1D81839D00D2AC35 /* ReaderOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED71D81838F00D2AC35 /* ReaderOverlayView.swift */; };
CE4E1EED1D81839D00D2AC35 /* SwitchCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED81D81838F00D2AC35 /* SwitchCameraButton.swift */; };
CE4E1EEE1D81839D00D2AC35 /* ToggleTorchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4E1ED91D81838F00D2AC35 /* ToggleTorchButton.swift */; };
CE8FFED91BAB4E7F00D43F38 /* QRCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = CE8FFED81BAB4E7F00D43F38 /* QRCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
CE8FFEEB1BAB4E7F00D43F38 /* QRCodeReader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE8FFED61BAB4E7F00D43F38 /* QRCodeReader.framework */; };
CE8FFEEC1BAB4E7F00D43F38 /* QRCodeReader.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CE8FFED61BAB4E7F00D43F38 /* QRCodeReader.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CE8FFEF41BAB4F5400D43F38 /* QRCodeReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED23DDB1A15079300BE7A72 /* QRCodeReader.swift */; };
CE8FFEF51BAB4F5400D43F38 /* SwitchCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED23DDD1A1507CB00BE7A72 /* SwitchCameraButton.swift */; };
CE8FFEF61BAB4F5400D43F38 /* ReaderOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCE4CC1A1527DE00071669 /* ReaderOverlayView.swift */; };
CE8FFEF71BAB4F5400D43F38 /* QRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECD170A1AA3531C00A9ACDE /* QRCodeViewController.swift */; };
CECCE4CD1A1527DE00071669 /* ReaderOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCE4CC1A1527DE00071669 /* ReaderOverlayView.swift */; };
CECD170B1AA3531C00A9ACDE /* QRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECD170A1AA3531C00A9ACDE /* QRCodeViewController.swift */; };
CED23DDC1A15079300BE7A72 /* QRCodeReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED23DDB1A15079300BE7A72 /* QRCodeReader.swift */; };
CED23DDE1A1507CB00BE7A72 /* SwitchCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED23DDD1A1507CB00BE7A72 /* SwitchCameraButton.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -65,9 +71,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
4A0723DB1C223D8100F2C410 /* QRCodeReaderResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReaderResult.swift; sourceTree = "<group>"; };
82BD4A091BBC21F800172E4E /* ToggleTorchButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleTorchButton.swift; sourceTree = "<group>"; };
CE345B221C444D6400FCC482 /* QRCodeViewControllerBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeViewControllerBuilder.swift; sourceTree = "<group>"; };
CE412E8919D9A1E4000F294E /* QRCodeReader.swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QRCodeReader.swift.app; sourceTree = BUILT_PRODUCTS_DIR; };
CE412E8D19D9A1E4000F294E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE412E8E19D9A1E4000F294E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -78,14 +81,17 @@
CE412E9E19D9A1E4000F294E /* QRCodeReader.swiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QRCodeReader.swiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
CE412EA319D9A1E4000F294E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE412EA419D9A1E4000F294E /* QRCodeReader_swiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeReader_swiftTests.swift; sourceTree = "<group>"; };
CE4E1ED31D81838F00D2AC35 /* QRCodeReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReader.swift; sourceTree = "<group>"; };
CE4E1ED41D81838F00D2AC35 /* QRCodeReaderResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReaderResult.swift; sourceTree = "<group>"; };
CE4E1ED51D81838F00D2AC35 /* QRCodeReaderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReaderViewController.swift; sourceTree = "<group>"; };
CE4E1ED61D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReaderViewControllerBuilder.swift; sourceTree = "<group>"; };
CE4E1ED71D81838F00D2AC35 /* ReaderOverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderOverlayView.swift; sourceTree = "<group>"; };
CE4E1ED81D81838F00D2AC35 /* SwitchCameraButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchCameraButton.swift; sourceTree = "<group>"; };
CE4E1ED91D81838F00D2AC35 /* ToggleTorchButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleTorchButton.swift; sourceTree = "<group>"; };
CE8FFED61BAB4E7F00D43F38 /* QRCodeReader.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = QRCodeReader.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CE8FFED81BAB4E7F00D43F38 /* QRCodeReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QRCodeReader.h; sourceTree = "<group>"; };
CE8FFEDA1BAB4E7F00D43F38 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CEC20A861A14EF0D00E7D0AD /* CameraSwitchIcon.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = CameraSwitchIcon.playground; path = resources/CameraSwitchIcon.playground; sourceTree = "<group>"; };
CECCE4CC1A1527DE00071669 /* ReaderOverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderOverlayView.swift; sourceTree = "<group>"; };
CECD170A1AA3531C00A9ACDE /* QRCodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeViewController.swift; sourceTree = "<group>"; };
CED23DDB1A15079300BE7A72 /* QRCodeReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReader.swift; sourceTree = "<group>"; };
CED23DDD1A1507CB00BE7A72 /* SwitchCameraButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchCameraButton.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -117,7 +123,7 @@
CE412E8019D9A1E4000F294E = {
isa = PBXGroup;
children = (
CED23DDA1A15079300BE7A72 /* QRCodeReader */,
CE4E1ED21D81838F00D2AC35 /* QRCodeReader */,
CE412E8B19D9A1E4000F294E /* Example */,
CE412EA119D9A1E4000F294E /* ExampleTests */,
CEC20A871A14EF1400E7D0AD /* Resources */,
@ -176,6 +182,21 @@
name = "Supporting Files";
sourceTree = "<group>";
};
CE4E1ED21D81838F00D2AC35 /* QRCodeReader */ = {
isa = PBXGroup;
children = (
CE4E1ED31D81838F00D2AC35 /* QRCodeReader.swift */,
CE4E1ED41D81838F00D2AC35 /* QRCodeReaderResult.swift */,
CE4E1ED51D81838F00D2AC35 /* QRCodeReaderViewController.swift */,
CE4E1ED61D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift */,
CE4E1ED71D81838F00D2AC35 /* ReaderOverlayView.swift */,
CE4E1ED81D81838F00D2AC35 /* SwitchCameraButton.swift */,
CE4E1ED91D81838F00D2AC35 /* ToggleTorchButton.swift */,
);
name = QRCodeReader;
path = ../Sources;
sourceTree = "<group>";
};
CE8FFED71BAB4E7F00D43F38 /* QRCodeReader */ = {
isa = PBXGroup;
children = (
@ -193,21 +214,6 @@
name = Resources;
sourceTree = "<group>";
};
CED23DDA1A15079300BE7A72 /* QRCodeReader */ = {
isa = PBXGroup;
children = (
4A0723DB1C223D8100F2C410 /* QRCodeReaderResult.swift */,
CED23DDB1A15079300BE7A72 /* QRCodeReader.swift */,
CED23DDD1A1507CB00BE7A72 /* SwitchCameraButton.swift */,
CECCE4CC1A1527DE00071669 /* ReaderOverlayView.swift */,
CECD170A1AA3531C00A9ACDE /* QRCodeViewController.swift */,
82BD4A091BBC21F800172E4E /* ToggleTorchButton.swift */,
CE345B221C444D6400FCC482 /* QRCodeViewControllerBuilder.swift */,
);
name = QRCodeReader;
path = ../QRCodeReader;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -284,18 +290,21 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Yannick Loriot";
TargetAttributes = {
CE412E8819D9A1E4000F294E = {
CreatedOnToolsVersion = 6.0.1;
LastSwiftMigration = 0800;
};
CE412E9D19D9A1E4000F294E = {
CreatedOnToolsVersion = 6.0.1;
LastSwiftMigration = 0800;
TestTargetID = CE412E8819D9A1E4000F294E;
};
CE8FFED51BAB4E7F00D43F38 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
};
};
};
@ -351,14 +360,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CECD170B1AA3531C00A9ACDE /* QRCodeViewController.swift in Sources */,
CE4E1EE01D81838F00D2AC35 /* ToggleTorchButton.swift in Sources */,
CE4E1EDF1D81838F00D2AC35 /* SwitchCameraButton.swift in Sources */,
CE412E9119D9A1E4000F294E /* ViewController.swift in Sources */,
82BD4A0A1BBC21F800172E4E /* ToggleTorchButton.swift in Sources */,
4A0723DC1C223D8100F2C410 /* QRCodeReaderResult.swift in Sources */,
CECCE4CD1A1527DE00071669 /* ReaderOverlayView.swift in Sources */,
CE345B231C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */,
CED23DDC1A15079300BE7A72 /* QRCodeReader.swift in Sources */,
CED23DDE1A1507CB00BE7A72 /* SwitchCameraButton.swift in Sources */,
CE4E1EDA1D81838F00D2AC35 /* QRCodeReader.swift in Sources */,
CE4E1EDE1D81838F00D2AC35 /* ReaderOverlayView.swift in Sources */,
CE4E1EDC1D81838F00D2AC35 /* QRCodeReaderViewController.swift in Sources */,
CE4E1EDB1D81838F00D2AC35 /* QRCodeReaderResult.swift in Sources */,
CE4E1EDD1D81838F00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */,
CE412E8F19D9A1E4000F294E /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -367,7 +376,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE345B241C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */,
CE4E1EE71D81839D00D2AC35 /* ToggleTorchButton.swift in Sources */,
CE4E1EE51D81839D00D2AC35 /* ReaderOverlayView.swift in Sources */,
CE4E1EE61D81839D00D2AC35 /* SwitchCameraButton.swift in Sources */,
CE4E1EE21D81839D00D2AC35 /* QRCodeReaderResult.swift in Sources */,
CE4E1EE41D81839D00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */,
CE4E1EE11D81839D00D2AC35 /* QRCodeReader.swift in Sources */,
CE4E1EE31D81839D00D2AC35 /* QRCodeReaderViewController.swift in Sources */,
CE412EA519D9A1E4000F294E /* QRCodeReader_swiftTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -376,13 +391,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE345B251C444D6400FCC482 /* QRCodeViewControllerBuilder.swift in Sources */,
4A0723DD1C22405100F2C410 /* QRCodeReaderResult.swift in Sources */,
82D83BA71BBC2A3100C94C22 /* ToggleTorchButton.swift in Sources */,
CE8FFEF41BAB4F5400D43F38 /* QRCodeReader.swift in Sources */,
CE8FFEF51BAB4F5400D43F38 /* SwitchCameraButton.swift in Sources */,
CE8FFEF61BAB4F5400D43F38 /* ReaderOverlayView.swift in Sources */,
CE8FFEF71BAB4F5400D43F38 /* QRCodeViewController.swift in Sources */,
CE4E1EEC1D81839D00D2AC35 /* ReaderOverlayView.swift in Sources */,
CE4E1EEA1D81839D00D2AC35 /* QRCodeReaderViewController.swift in Sources */,
CE4E1EEB1D81839D00D2AC35 /* QRCodeReaderViewControllerBuilder.swift in Sources */,
CE4E1EE81D81839D00D2AC35 /* QRCodeReader.swift in Sources */,
CE4E1EED1D81839D00D2AC35 /* SwitchCameraButton.swift in Sources */,
CE4E1EEE1D81839D00D2AC35 /* ToggleTorchButton.swift in Sources */,
CE4E1EE91D81839D00D2AC35 /* QRCodeReaderResult.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -444,6 +459,7 @@
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@ -487,6 +503,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@ -504,24 +521,29 @@
CE412EA919D9A1E4000F294E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = QRCodeReader.swift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.yannickloriot.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
CE412EAA19D9A1E4000F294E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = QRCodeReader.swift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.yannickloriot.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -541,6 +563,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.yannickloriot.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/QRCodeReader.swift.app/QRCodeReader.swift";
};
name = Debug;
@ -557,6 +580,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.yannickloriot.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/QRCodeReader.swift.app/QRCodeReader.swift";
};
name = Release;
@ -578,6 +603,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.yannickloriot.QRCodeReader;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -601,6 +627,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.yannickloriot.QRCodeReader;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -31,31 +31,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<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">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
@ -14,17 +15,17 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="1024" height="1366"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P5n-CT-PTt">
<rect key="frame" x="222" y="225" width="155" height="150"/>
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P5n-CT-PTt">
<frame key="frameInset" minX="222" minY="225" width="155" height="150"/>
<constraints>
<constraint firstAttribute="width" constant="155" id="O9u-YB-D6M"/>
<constraint firstAttribute="height" constant="150" id="h6v-qf-cpj"/>
</constraints>
<state key="normal" title="Scan">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="scanAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Tum-8Y-xC0"/>
@ -56,7 +57,7 @@
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="B2g-a5-1sz" firstAttribute="top" secondItem="P5n-CT-PTt" secondAttribute="bottom" constant="-4" id="17H-xA-CBR"/>
<constraint firstAttribute="centerX" secondItem="P5n-CT-PTt" secondAttribute="centerX" constant="0.5" id="CeZ-ED-sHl"/>

View File

@ -15,13 +15,15 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>6.2.0</string>
<string>7.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Used to scan QR codes</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

View File

@ -28,13 +28,14 @@ import UIKit
import AVFoundation
class ViewController: UIViewController, QRCodeReaderViewControllerDelegate {
lazy var reader = QRCodeReaderViewController(builder: QRCodeReaderViewControllerBuilder {
$0.reader = QRCodeReader(metadataObjectTypes: [AVMetadataObjectTypeQRCode])
$0.showTorchButton = true
})
@IBOutlet weak var showCancelButtonSwitch: UISwitch!
@IBAction func scanAction(sender: AnyObject) {
@IBAction func scanAction(_ sender: AnyObject) {
if QRCodeReader.supportsMetadataObjectTypes() {
let reader = createReader()
reader.modalPresentationStyle = .FormSheet
reader.modalPresentationStyle = .formSheet
reader.delegate = self
reader.completionBlock = { (result: QRCodeReaderResult?) in
@ -43,33 +44,33 @@ class ViewController: UIViewController, QRCodeReaderViewControllerDelegate {
}
}
presentViewController(reader, animated: true, completion: nil)
present(reader, animated: true, completion: nil)
}
else {
let alert = UIAlertController(title: "Error", message: "Reader not supported by the current device", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
let alert = UIAlertController(title: "Error", message: "Reader not supported by the current device", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
presentViewController(alert, animated: true, completion: nil)
present(alert, animated: true, completion: nil)
}
}
// MARK: - QRCodeReader Delegate Methods
func reader(reader: QRCodeReaderViewController, didScanResult result: QRCodeReaderResult) {
self.dismissViewControllerAnimated(true) { [weak self] in
func reader(_ reader: QRCodeReaderViewController, didScanResult result: QRCodeReaderResult) {
dismiss(animated: true) { [weak self] in
let alert = UIAlertController(
title: "QRCodeReader",
message: String (format:"%@ (of type %@)", result.value, result.metadataType),
preferredStyle: .Alert
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self?.presentViewController(alert, animated: true, completion: nil)
self?.present(alert, animated: true, completion: nil)
}
}
func readerDidCancel(reader: QRCodeReaderViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
func readerDidCancel(_ reader: QRCodeReaderViewController) {
dismiss(animated: true, completion: nil)
}
private func createReader() -> QRCodeReaderViewController {

View File

@ -10,27 +10,5 @@ import UIKit
import XCTest
class QRCodeReader_swiftTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock() {
// Put the code you want to measure the time of here.
}
}
}

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>6.2.0</string>
<string>7.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

31
Package.swift Normal file
View File

@ -0,0 +1,31 @@
//
// QRCodeReader.swift
//
// Copyright 2014-present Yannick Loriot.
// http://yannickloriot.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import PackageDescription
let package = Package(
name: "QRCodeReader"
)

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'QRCodeReader.swift'
s.module_name = 'QRCodeReader'
s.version = '6.2.0'
s.version = '7.0.0'
s.license = 'MIT'
s.summary = 'Simple QRCode and 1D bar code reader in Swift'
s.homepage = 'https://github.com/yannickl/QRCodeReader.swift.git'
@ -13,6 +13,6 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '8.0'
s.framework = 'AVFoundation'
s.source_files = 'QRCodeReader/*.swift'
s.source_files = 'Sources/*.swift'
s.requires_arc = true
end

View File

@ -8,6 +8,8 @@ It provides a default view controller to display the camera view with the scan a
![screenshot](http://yannickloriot.com/resources/qrcodereader.swift-screenshot.jpg)
*Note: the v6.x supports the Swift 2.2.*
## Usage
- Add delegate `QRCodeReaderViewControllerDelegate`
@ -17,11 +19,11 @@ It provides a default view controller to display the camera view with the scan a
```swift
// Good practice: create the reader lazily to avoid cpu overload during the
// initialization and each time we need to scan a QRCode
lazy var readerVC = QRCodeReaderViewController(builder: QRCodeViewControllerBuilder {
lazy var readerVC = QRCodeReaderViewController(builder: QRCodeReaderViewControllerBuilder {
$0.reader = QRCodeReader(metadataObjectTypes: [AVMetadataObjectTypeQRCode])
})
@IBAction func scanAction(sender: AnyObject) {
@IBAction func scanAction(_ sender: AnyObject) {
// Retrieve the QRCode content
// By using the delegate pattern
readerVC.delegate = self
@ -32,18 +34,18 @@ lazy var readerVC = QRCodeReaderViewController(builder: QRCodeViewControllerBuil
}
// Presents the readerVC as modal form sheet
readerVC.modalPresentationStyle = .FormSheet
presentViewController(readerVC, animated: true, completion: nil)
readerVC.modalPresentationStyle = .formSheet
present(reader, animated: true, completion: nil)
}
// MARK: - QRCodeReaderViewController Delegate Methods
func reader(reader: QRCodeReaderViewController, didScanResult result: QRCodeReaderResult) {
self.dismissViewControllerAnimated(true, completion: nil)
func reader(_ reader: QRCodeReader, didScanResult result: QRCodeReaderResult) {
dismiss(animated: true, completion: nil)
}
func readerDidCancel(reader: QRCodeReaderViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
func readerDidCancel(_ reader: QRCodeReader) {
dismiss(animated: true, completion: nil)
}
```
@ -72,7 +74,7 @@ platform :ios, '8.0'
use_frameworks!
target 'TargetName' do
pod 'QRCodeReader.swift', '~> 6.2.0'
pod 'QRCodeReader.swift', '~> 7.0.0'
end
```
@ -104,9 +106,27 @@ $ brew install carthage
To integrate `QRCodeReader` into your Xcode project using Carthage, specify it in your `Cartfile` file:
```ogdl
github "yannickl/QRCodeReader.swift" >= 6.2.0
github "yannickl/QRCodeReader.swift" >= 7.0.0
```
#### Swift Package Manager
You can use [The Swift Package Manager](https://swift.org/package-manager) to install `QRCodeReader.swift` by adding the proper description to your `Package.swift` file:
```swift
import PackageDescription
let package = Package(
name: "YOUR_PROJECT_NAME",
targets: [],
dependencies: [
.Package(url: "https://github.com/yannickl/QRCodeReader.swift.git", versions: "7.0.0" ..< Version.max)
]
)
```
Note that the [Swift Package Manager](https://swift.org/package-manager) is still in early design and development, for more information checkout its [GitHub Page](https://github.com/apple/swift-package-manager)
#### Manually
[Download](https://github.com/YannickL/QRCodeReader.swift/archive/master.zip) the project and copy the `QRCodeReader` folder into your project to use it in.

View File

@ -29,11 +29,16 @@ import AVFoundation
/// Reader object base on the `AVCaptureDevice` to read / scan 1D and 2D codes.
public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegate {
var defaultDevice: AVCaptureDevice = .defaultDeviceWithMediaType(AVMediaTypeVideo)
var defaultDevice: AVCaptureDevice = .defaultDevice(withMediaType: AVMediaTypeVideo)
var frontDevice: AVCaptureDevice? = {
for device in AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) {
if let _device = device as? AVCaptureDevice where _device.position == AVCaptureDevicePosition.Front {
return _device
if #available(iOS 10, *) {
return .defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front)
}
else {
for device in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) {
if let _device = device as? AVCaptureDevice , _device.position == AVCaptureDevicePosition.front {
return _device
}
}
}
@ -71,7 +76,7 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
public var stopScanningWhenCodeIsFound: Bool = true
/// Block is executed when a metadata object is found.
public var didFindCodeBlock: (QRCodeReaderResult -> Void)?
public var didFindCode: ((QRCodeReaderResult) -> Void)?
// MARK: - Creating the Code Reader
@ -104,7 +109,7 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
session.addInput(_defaultDeviceInput)
}
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = metadataObjectTypes
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
}
@ -117,7 +122,7 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
if let _currentInput = session.inputs.first as? AVCaptureDeviceInput {
session.removeInput(_currentInput)
let newDeviceInput = (_currentInput.device.position == .Front) ? defaultDeviceInput : _frontDeviceInput
let newDeviceInput = (_currentInput.device.position == .front) ? defaultDeviceInput : _frontDeviceInput
session.addInput(newDeviceInput)
}
@ -133,14 +138,14 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
*Notes: if `stopScanningWhenCodeIsFound` is sets to true (default behaviour), each time the scanner found a code it calls the `stopScanning` method.*
*/
public func startScanning() {
if !session.running {
if !session.isRunning {
session.startRunning()
}
}
/// Stops scanning the codes.
public func stopScanning() {
if session.running {
if session.isRunning {
session.stopRunning()
}
}
@ -152,28 +157,26 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
Clients can key value observe the value of this property to be notified when
the session automatically starts or stops running.
*/
public var running: Bool {
get {
return session.running
}
public var isRunning: Bool {
return session.isRunning
}
/**
Returns true whether a front device is available.
Indicates whether a front device is available.
- returns: true whether the device has a front device.
*/
public func hasFrontDevice() -> Bool {
public var hasFrontDevice: Bool {
return frontDevice != nil
}
/**
Returns true whether a torch is available.
Indicates whether the torch is available.
- returns: true if a torch is available.
*/
public func isTorchAvailable() -> Bool {
return defaultDevice.torchAvailable
public var isTorchAvailable: Bool {
return defaultDevice.isTorchAvailable
}
/**
@ -183,8 +186,8 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
do {
try defaultDevice.lockForConfiguration()
let current = defaultDevice.torchMode
defaultDevice.torchMode = AVCaptureTorchMode.On == current ? .Off : .On
let current = defaultDevice.torchMode
defaultDevice.torchMode = AVCaptureTorchMode.on == current ? .off : .on
defaultDevice.unlockForConfiguration()
}
@ -200,54 +203,54 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
- parameter supportedOrientations: The supported orientations of the application.
- parameter fallbackOrientation: The video orientation if the device orientation is FaceUp or FaceDown.
*/
public class func videoOrientationFromDeviceOrientation(orientation: UIDeviceOrientation, withSupportedOrientations supportedOrientations: UIInterfaceOrientationMask, fallbackOrientation: AVCaptureVideoOrientation? = nil) -> AVCaptureVideoOrientation {
public class func videoOrientation(deviceOrientation orientation: UIDeviceOrientation, withSupportedOrientations supportedOrientations: UIInterfaceOrientationMask, fallbackOrientation: AVCaptureVideoOrientation? = nil) -> AVCaptureVideoOrientation {
let result: AVCaptureVideoOrientation
switch (orientation, fallbackOrientation) {
case (.LandscapeLeft, _):
result = .LandscapeRight
case (.LandscapeRight, _):
result = .LandscapeLeft
case (.Portrait, _):
result = .Portrait
case (.PortraitUpsideDown, _):
result = .PortraitUpsideDown
case (_, .Some(let orientation)):
case (.landscapeLeft, _):
result = .landscapeRight
case (.landscapeRight, _):
result = .landscapeLeft
case (.portrait, _):
result = .portrait
case (.portraitUpsideDown, _):
result = .portraitUpsideDown
case (_, .some(let orientation)):
result = orientation
default:
result = .Portrait
result = .portrait
}
if supportedOrientations.contains(orientationMaskWithVideoOrientation(result)) {
if supportedOrientations.contains(orientationMask(videoOrientation: result)) {
return result
}
else if let orientation = fallbackOrientation where supportedOrientations.contains(orientationMaskWithVideoOrientation(orientation)) {
else if let orientation = fallbackOrientation , supportedOrientations.contains(orientationMask(videoOrientation: orientation)) {
return orientation
}
else if supportedOrientations.contains(.Portrait) {
return .Portrait
else if supportedOrientations.contains(.portrait) {
return .portrait
}
else if supportedOrientations.contains(.LandscapeLeft) {
return .LandscapeLeft
else if supportedOrientations.contains(.landscapeLeft) {
return .landscapeLeft
}
else if supportedOrientations.contains(.LandscapeRight) {
return .LandscapeRight
else if supportedOrientations.contains(.landscapeRight) {
return .landscapeRight
}
else {
return .PortraitUpsideDown
return .portraitUpsideDown
}
}
class func orientationMaskWithVideoOrientation(orientation: AVCaptureVideoOrientation) -> UIInterfaceOrientationMask {
class func orientationMask(videoOrientation orientation: AVCaptureVideoOrientation) -> UIInterfaceOrientationMask {
switch orientation {
case .LandscapeLeft:
return .LandscapeLeft
case .LandscapeRight:
return .LandscapeRight
case .Portrait:
return .Portrait
case .PortraitUpsideDown:
return .PortraitUpsideDown
case .landscapeLeft:
return .landscapeLeft
case .landscapeRight:
return .landscapeRight
case .portrait:
return .portrait
case .portraitUpsideDown:
return .portraitUpsideDown
}
}
@ -259,12 +262,8 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
- returns: A boolean value that indicates whether the reader is available.
*/
public class func isAvailable() -> Bool {
if AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo).count == 0 {
return false
}
do {
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
let _ = try AVCaptureDeviceInput(device: captureDevice)
return true
@ -280,13 +279,13 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
- returns: A boolean value that indicates whether the device supports the given metadata object types.
*/
public class func supportsMetadataObjectTypes(metadataTypes: [String]? = nil) -> Bool {
public class func supportsMetadataObjectTypes(_ metadataTypes: [String]? = nil) -> Bool {
if !isAvailable() {
return false
}
// Setup components
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
let deviceInput = try! AVCaptureDeviceInput(device: captureDevice)
let output = AVCaptureMetadataOutput()
let session = AVCaptureSession()
@ -302,7 +301,7 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
}
for metadataObjectType in metadataObjectTypes! {
if !output.availableMetadataObjectTypes.contains({ $0 as! String == metadataObjectType }) {
if !output.availableMetadataObjectTypes.contains(where: { $0 as! String == metadataObjectType }) {
return false
}
}
@ -312,7 +311,8 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
// MARK: - AVCaptureMetadataOutputObjects Delegate Methods
public func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
public func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
for current in metadataObjects {
if let _readableCodeObject = current as? AVMetadataMachineReadableCodeObject {
if metadataObjectTypes.contains(_readableCodeObject.type) {
@ -322,8 +322,8 @@ public final class QRCodeReader: NSObject, AVCaptureMetadataOutputObjectsDelegat
let scannedResult = QRCodeReaderResult(value: _readableCodeObject.stringValue, metadataType:_readableCodeObject.type)
dispatch_async(dispatch_get_main_queue(), { [weak self] in
self?.didFindCodeBlock?(scannedResult)
DispatchQueue.main.async(execute: { [weak self] in
self?.didFindCode?(scannedResult)
})
}
}

View File

@ -39,4 +39,4 @@ public struct QRCodeReaderResult {
The type of the metadata.
*/
public let metadataType: String
}
}

View File

@ -0,0 +1,262 @@
/*
* QRCodeReader.swift
*
* Copyright 2014-present Yannick Loriot.
* http://yannickloriot.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
import UIKit
import AVFoundation
/// Convenient controller to display a view to scan/read 1D or 2D bar codes like the QRCodes. It is based on the `AVFoundation` framework from Apple. It aims to replace ZXing or ZBar for iOS 7 and over.
public class QRCodeReaderViewController: UIViewController {
private var cameraView = ReaderOverlayView()
private var cancelButton: UIButton?
private var switchCameraButton: SwitchCameraButton?
private var toggleTorchButton: ToggleTorchButton?
/// The code reader object used to scan the bar code.
public let codeReader: QRCodeReader
let startScanningAtLoad: Bool
let showCancelButton: Bool
let showSwitchCameraButton: Bool
let showTorchButton: Bool
// MARK: - Managing the Callback Responders
/// The receiver's delegate that will be called when a result is found.
public weak var delegate: QRCodeReaderViewControllerDelegate?
/// The completion blocak that will be called when a result is found.
public var completionBlock: ((QRCodeReaderResult?) -> Void)?
deinit {
codeReader.stopScanning()
NotificationCenter.default.removeObserver(self)
}
// MARK: - Creating the View Controller
/**
Initializes a view controller using a builder.
- parameter builder: A QRCodeViewController builder object.
*/
required public init(builder: QRCodeReaderViewControllerBuilder) {
startScanningAtLoad = builder.startScanningAtLoad
codeReader = builder.reader
showCancelButton = builder.showCancelButton
showSwitchCameraButton = builder.showSwitchCameraButton
showTorchButton = builder.showTorchButton
super.init(nibName: nil, bundle: nil)
view.backgroundColor = .black
codeReader.didFindCode = { [weak self] resultAsObject in
if let weakSelf = self {
weakSelf.completionBlock?(resultAsObject)
weakSelf.delegate?.reader(weakSelf, didScanResult: resultAsObject)
}
}
setupUIComponentsWithCancelButtonTitle(builder.cancelButtonTitle)
setupAutoLayoutConstraints()
cameraView.layer.insertSublayer(codeReader.previewLayer, at: 0)
NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
required public init?(coder aDecoder: NSCoder) {
codeReader = QRCodeReader(metadataObjectTypes: [])
startScanningAtLoad = false
showCancelButton = false
showTorchButton = false
showSwitchCameraButton = false
super.init(coder: aDecoder)
}
// MARK: - Responding to View Events
override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return parent?.supportedInterfaceOrientations ?? .all
}
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if startScanningAtLoad {
startScanning()
}
}
override public func viewWillDisappear(_ animated: Bool) {
stopScanning()
super.viewWillDisappear(animated)
}
override public func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
codeReader.previewLayer.frame = view.bounds
}
// MARK: - Managing the Orientation
func orientationDidChanged(_ notification: Notification) {
cameraView.setNeedsDisplay()
if let device = notification.object as? UIDevice , codeReader.previewLayer.connection.isVideoOrientationSupported {
codeReader.previewLayer.connection.videoOrientation = QRCodeReader.videoOrientation(deviceOrientation: device.orientation, withSupportedOrientations: supportedInterfaceOrientations, fallbackOrientation: codeReader.previewLayer.connection.videoOrientation)
}
}
// MARK: - Initializing the AV Components
private func setupUIComponentsWithCancelButtonTitle(_ cancelButtonTitle: String) {
cameraView.clipsToBounds = true
cameraView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cameraView)
codeReader.previewLayer.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)
if codeReader.previewLayer.connection.isVideoOrientationSupported {
let orientation = UIDevice.current.orientation
codeReader.previewLayer.connection.videoOrientation = QRCodeReader.videoOrientation(deviceOrientation: orientation, withSupportedOrientations: supportedInterfaceOrientations)
}
if showSwitchCameraButton && codeReader.hasFrontDevice {
let newSwitchCameraButton = SwitchCameraButton()
newSwitchCameraButton.translatesAutoresizingMaskIntoConstraints = false
newSwitchCameraButton.addTarget(self, action: #selector(switchCameraAction), for: .touchUpInside)
view.addSubview(newSwitchCameraButton)
switchCameraButton = newSwitchCameraButton
}
if showTorchButton && codeReader.isTorchAvailable {
let newToggleTorchButton = ToggleTorchButton()
newToggleTorchButton.translatesAutoresizingMaskIntoConstraints = false
newToggleTorchButton.addTarget(self, action: #selector(toggleTorchAction), for: .touchUpInside)
view.addSubview(newToggleTorchButton)
toggleTorchButton = newToggleTorchButton
}
if showCancelButton {
let newCancelButton = UIButton()
newCancelButton.translatesAutoresizingMaskIntoConstraints = false
newCancelButton.setTitle(cancelButtonTitle, for: .normal)
newCancelButton.setTitleColor(.gray, for: .highlighted)
newCancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
view.addSubview(newCancelButton)
cancelButton = newCancelButton
}
}
private func setupAutoLayoutConstraints() {
let views = ["cameraView": cameraView]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[cameraView]|", options: [], metrics: nil, views: views))
if let _cancelButton = cancelButton {
let cancelViews: [String: UIView] = ["cancelButton": _cancelButton, "cameraView": cameraView]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[cameraView][cancelButton(40)]|", options: [], metrics: nil, views: cancelViews))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[cancelButton]-|", options: [], metrics: nil, views: cancelViews))
}
else {
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[cameraView]|", options: [], metrics: nil, views: views))
}
if let _switchCameraButton = switchCameraButton {
let switchViews: [String: AnyObject] = ["switchCameraButton": _switchCameraButton, "topGuide": topLayoutGuide]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[topGuide]-[switchCameraButton(50)]", options: [], metrics: nil, views: switchViews))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[switchCameraButton(70)]|", options: [], metrics: nil, views: switchViews))
}
if let _toggleTorchButton = toggleTorchButton {
let toggleViews: [String: AnyObject] = ["toggleTorchButton": _toggleTorchButton, "topGuide": topLayoutGuide]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[topGuide]-[toggleTorchButton(50)]", options: [], metrics: nil, views: toggleViews))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[toggleTorchButton(70)]", options: [], metrics: nil, views: toggleViews))
}
}
// MARK: - Controlling the Reader
/// Starts scanning the codes.
public func startScanning() {
codeReader.startScanning()
}
/// Stops scanning the codes.
public func stopScanning() {
codeReader.stopScanning()
}
// MARK: - Catching Button Events
func cancelAction(_ button: UIButton) {
codeReader.stopScanning()
if let _completionBlock = completionBlock {
_completionBlock(nil)
}
delegate?.readerDidCancel(self)
}
func switchCameraAction(_ button: SwitchCameraButton) {
codeReader.switchDeviceInput()
}
func toggleTorchAction(_ button: ToggleTorchButton) {
codeReader.toggleTorch()
}
}
/**
This protocol defines delegate methods for objects that implements the `QRCodeReaderDelegate`. The methods of the protocol allow the delegate to be notified when the reader did scan result and or when the user wants to stop to read some QRCodes.
*/
public protocol QRCodeReaderViewControllerDelegate: class {
/**
Tells the delegate that the reader did scan a code.
- parameter reader: A code reader object informing the delegate about the scan result.
- parameter result: The result of the scan
*/
func reader(_ reader: QRCodeReaderViewController, didScanResult result: QRCodeReaderResult)
/**
Tells the delegate that the user wants to stop scanning codes.
- parameter reader: A code reader object informing the delegate about the cancellation.
*/
func readerDidCancel(_ reader: QRCodeReaderViewController)
}

View File

@ -30,14 +30,14 @@ import Foundation
The QRCodeViewControllerBuilder aims to create a simple configuration object for
the QRCode view controller.
*/
public final class QRCodeViewControllerBuilder {
public final class QRCodeReaderViewControllerBuilder {
// MARK: - Configuring the QRCodeViewController Objects
/**
The builder block.
The block gives a reference of builder you can configure.
*/
public typealias QRCodeViewControllerBuilderBlock = (builder: QRCodeViewControllerBuilder) -> Void
public typealias QRCodeReaderViewControllerBuilderBlock = (QRCodeReaderViewControllerBuilder) -> Void
/**
The title to use for the cancel button.
@ -54,6 +54,11 @@ public final class QRCodeViewControllerBuilder {
*/
public var startScanningAtLoad = true
/**
Flag to display the cancel button.
*/
public var showCancelButton = true
/**
Flag to display the switch camera button.
*/
@ -77,11 +82,11 @@ public final class QRCodeViewControllerBuilder {
public init() {}
/**
Initialize a QRCodeViewController builder with default values.
Initialize a QRCodeReaderViewController builder with default values.
- parameter buildBlock: A QRCodeViewController builder block to configure itself.
- parameter buildBlock: A QRCodeReaderViewController builder block to configure itself.
*/
public init(@noescape buildBlock: QRCodeViewControllerBuilderBlock) {
buildBlock(builder: self)
public init(buildBlock: QRCodeReaderViewControllerBuilderBlock) {
buildBlock(self)
}
}
}

View File

@ -30,9 +30,9 @@ import UIKit
final class ReaderOverlayView: UIView {
private var overlay: CAShapeLayer = {
var overlay = CAShapeLayer()
overlay.backgroundColor = UIColor.clearColor().CGColor
overlay.fillColor = UIColor.clearColor().CGColor
overlay.strokeColor = UIColor.whiteColor().CGColor
overlay.backgroundColor = UIColor.clear.cgColor
overlay.fillColor = UIColor.clear.cgColor
overlay.strokeColor = UIColor.white.cgColor
overlay.lineWidth = 3
overlay.lineDashPattern = [7.0, 7.0]
overlay.lineDashPhase = 0
@ -41,7 +41,7 @@ final class ReaderOverlayView: UIView {
}()
init() {
super.init(frame: CGRectZero) // Workaround for init in iOS SDK 8.3
super.init(frame: CGRect.zero) // Workaround for init in iOS SDK 8.3
layer.addSublayer(overlay)
}
@ -58,8 +58,8 @@ final class ReaderOverlayView: UIView {
layer.addSublayer(overlay)
}
override func drawRect(rect: CGRect) {
var innerRect = CGRectInset(rect, 50, 50)
override func draw(_ rect: CGRect) {
var innerRect = rect.insetBy(dx: 50, dy: 50)
let minSize = min(innerRect.width, innerRect.height)
if innerRect.width != minSize {
@ -71,8 +71,8 @@ final class ReaderOverlayView: UIView {
innerRect.size.height = minSize
}
let offsetRect = CGRectOffset(innerRect, 0, 15)
let offsetRect = innerRect.offsetBy(dx: 0, dy: 15)
overlay.path = UIBezierPath(roundedRect: offsetRect, cornerRadius: 5).CGPath
overlay.path = UIBezierPath(roundedRect: offsetRect, cornerRadius: 5).cgPath
}
}

View File

@ -28,22 +28,22 @@ import UIKit
/// The camera switch button.
@IBDesignable final class SwitchCameraButton: UIButton {
@IBInspectable var edgeColor: UIColor = .whiteColor() {
@IBInspectable var edgeColor: UIColor = UIColor.white {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var fillColor: UIColor = .darkGrayColor() {
@IBInspectable var fillColor: UIColor = UIColor.darkGray {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var edgeHighlightedColor: UIColor = .whiteColor()
@IBInspectable var fillHighlightedColor: UIColor = .blackColor()
@IBInspectable var edgeHighlightedColor: UIColor = UIColor.white
@IBInspectable var fillHighlightedColor: UIColor = UIColor.black
override func drawRect(rect: CGRect) {
override func draw(_ rect: CGRect) {
let width = rect.width
let height = rect.height
let center = width / 2
@ -52,8 +52,8 @@ import UIKit
let strokeLineWidth = CGFloat(2)
// Colors
let paintColor = (self.state != .Highlighted) ? fillColor : fillHighlightedColor
let strokeColor = (self.state != .Highlighted) ? edgeColor : edgeHighlightedColor
let paintColor = (self.state != .highlighted) ? fillColor : fillHighlightedColor
let strokeColor = (self.state != .highlighted) ? edgeColor : edgeHighlightedColor
// Camera box
let cameraWidth = width * 0.4
@ -73,8 +73,8 @@ import UIKit
let innerLensX = center - innerLensSize / 2
let innerLensY = middle - innerLensSize / 2
let outerLensPath = UIBezierPath(ovalInRect: CGRect(x: outerLensX, y: outerLensY, width: outerLensSize, height: outerLensSize))
let innerLensPath = UIBezierPath(ovalInRect: CGRect(x: innerLensX, y: innerLensY, width: innerLensSize, height: innerLensSize))
let outerLensPath = UIBezierPath(ovalIn: CGRect(x: outerLensX, y: outerLensY, width: outerLensSize, height: outerLensSize))
let innerLensPath = UIBezierPath(ovalIn: CGRect(x: innerLensX, y: innerLensY, width: innerLensSize, height: innerLensSize))
// Draw flash box
let flashBoxWidth = cameraWidth * 0.8
@ -84,13 +84,13 @@ import UIKit
let flashBottomMostY = cameraY
let flashPath = UIBezierPath()
flashPath.moveToPoint(CGPoint(x: flashLeftMostX, y: flashBottomMostY))
flashPath.addLineToPoint(CGPoint(x: flashLeftMostX + flashBoxWidth, y: flashBottomMostY))
flashPath.addLineToPoint(CGPoint(x: flashLeftMostX + flashBoxWidth - flashBoxDeltaWidth, y: flashBottomMostY - flashBoxHeight))
flashPath.addLineToPoint(CGPoint(x: flashLeftMostX + flashBoxDeltaWidth, y: flashBottomMostY - flashBoxHeight))
flashPath.closePath()
flashPath.lineCapStyle = .Round
flashPath.lineJoinStyle = .Round
flashPath.move(to: CGPoint(x: flashLeftMostX, y: flashBottomMostY))
flashPath.addLine(to: CGPoint(x: flashLeftMostX + flashBoxWidth, y: flashBottomMostY))
flashPath.addLine(to: CGPoint(x: flashLeftMostX + flashBoxWidth - flashBoxDeltaWidth, y: flashBottomMostY - flashBoxHeight))
flashPath.addLine(to: CGPoint(x: flashLeftMostX + flashBoxDeltaWidth, y: flashBottomMostY - flashBoxHeight))
flashPath.close()
flashPath.lineCapStyle = .round
flashPath.lineJoinStyle = .round
// Arrows
let arrowHeadHeigth = cameraHeight * 0.5
@ -103,27 +103,27 @@ import UIKit
let arrowLeftY = middle + cameraHeight * 0.45
let leftArrowPath = UIBezierPath()
leftArrowPath.moveToPoint(CGPoint(x: arrowLeftX, y: arrowLeftY))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY - arrowHeadHeigth / 2))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY - arrowTailHeigth / 2))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth - arrowTailWidth, y: arrowLeftY - arrowTailHeigth / 2))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth - arrowTailWidth, y: arrowLeftY + arrowTailHeigth / 2))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY + arrowTailHeigth / 2))
leftArrowPath.addLineToPoint(CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY + arrowHeadHeigth / 2))
leftArrowPath.move(to: CGPoint(x: arrowLeftX, y: arrowLeftY))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY - arrowHeadHeigth / 2))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY - arrowTailHeigth / 2))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth - arrowTailWidth, y: arrowLeftY - arrowTailHeigth / 2))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth - arrowTailWidth, y: arrowLeftY + arrowTailHeigth / 2))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY + arrowTailHeigth / 2))
leftArrowPath.addLine(to: CGPoint(x: arrowLeftX - arrowHeadWidth, y: arrowLeftY + arrowHeadHeigth / 2))
// Right arrow
let arrowRightX = center + cameraWidth * 0.2
let arrowRightY = middle + cameraHeight * 0.60
let rigthArrowPath = UIBezierPath()
rigthArrowPath.moveToPoint(CGPoint(x: arrowRightX, y: arrowRightY))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY - arrowHeadHeigth / 2))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY - arrowTailHeigth / 2))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth + arrowTailWidth, y: arrowRightY - arrowTailHeigth / 2))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth + arrowTailWidth, y: arrowRightY + arrowTailHeigth / 2))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY + arrowTailHeigth / 2))
rigthArrowPath.addLineToPoint(CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY + arrowHeadHeigth / 2))
rigthArrowPath.closePath()
rigthArrowPath.move(to: CGPoint(x: arrowRightX, y: arrowRightY))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY - arrowHeadHeigth / 2))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY - arrowTailHeigth / 2))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth + arrowTailWidth, y: arrowRightY - arrowTailHeigth / 2))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth + arrowTailWidth, y: arrowRightY + arrowTailHeigth / 2))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY + arrowTailHeigth / 2))
rigthArrowPath.addLine(to: CGPoint(x: arrowRightX + arrowHeadWidth, y: arrowRightY + arrowHeadHeigth / 2))
rigthArrowPath.close()
// Drawing
paintColor.setFill()
@ -150,7 +150,7 @@ import UIKit
flashPath.lineWidth = strokeLineWidth
flashPath.stroke()
leftArrowPath.closePath()
leftArrowPath.close()
paintColor.setFill()
leftArrowPath.fill()
strokeColor.setStroke()
@ -160,26 +160,26 @@ import UIKit
// MARK: - UIResponder Methods
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
setNeedsDisplay()
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesMoved(touches, withEvent: event)
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
setNeedsDisplay()
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
setNeedsDisplay()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
super.touchesCancelled(touches!, with: event)
setNeedsDisplay()
}
}
}

View File

@ -28,25 +28,25 @@ import UIKit
/// The toggle torch button.
@IBDesignable final class ToggleTorchButton: UIButton {
@IBInspectable var edgeColor: UIColor = .whiteColor() {
@IBInspectable var edgeColor: UIColor = UIColor.white {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var fillColor: UIColor = .lightGrayColor() {
@IBInspectable var fillColor: UIColor = UIColor.lightGray {
didSet {
setNeedsDisplay()
}
}
@IBInspectable var edgeHighlightedColor: UIColor = .whiteColor()
@IBInspectable var fillHighlightedColor: UIColor = .darkGrayColor()
@IBInspectable var edgeHighlightedColor: UIColor = UIColor.white
@IBInspectable var fillHighlightedColor: UIColor = UIColor.darkGray
override func drawRect(rect: CGRect) {
override func draw(_ rect: CGRect) {
// Colors
let paintColor = (self.state != .Highlighted) ? fillColor : fillHighlightedColor
let strokeColor = (self.state != .Highlighted) ? edgeColor : edgeHighlightedColor
let paintColor = (self.state != .highlighted) ? fillColor : fillHighlightedColor
let strokeColor = (self.state != .highlighted) ? edgeColor : edgeHighlightedColor
let width = rect.width
let height = rect.height
@ -62,8 +62,8 @@ import UIKit
//Circle
let circlePath = UIBezierPath()
let center = CGPoint(x: centerX, y: centerY)
circlePath.addArcWithCenter(center, radius: circleRadius, startAngle: 0.0, endAngle: CGFloat(M_PI), clockwise: true)
circlePath.addArcWithCenter(center, radius: circleRadius, startAngle: CGFloat(M_PI), endAngle: CGFloat(M_PI * 2), clockwise: true)
circlePath.addArc(withCenter: center, radius: circleRadius, startAngle: 0.0, endAngle: CGFloat(M_PI), clockwise: true)
circlePath.addArc(withCenter: center, radius: circleRadius, startAngle: CGFloat(M_PI), endAngle: CGFloat(M_PI * 2), clockwise: true)
// Draw beams
paintColor.setFill()
@ -86,12 +86,12 @@ import UIKit
circlePath.stroke()
}
private func linePathWithStartPoint(startPoint: CGPoint, endPoint: CGPoint, thickness: CGFloat) -> UIBezierPath {
private func linePathWithStartPoint(_ startPoint: CGPoint, endPoint: CGPoint, thickness: CGFloat) -> UIBezierPath {
let linePath = UIBezierPath()
linePath.moveToPoint(startPoint)
linePath.addLineToPoint(endPoint)
linePath.lineCapStyle = .Round
linePath.move(to: startPoint)
linePath.addLine(to: endPoint)
linePath.lineCapStyle = .round
linePath.lineWidth = thickness
return linePath
@ -99,26 +99,26 @@ import UIKit
// MARK: - UIResponder Methods
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
setNeedsDisplay()
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesMoved(touches, withEvent: event)
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
setNeedsDisplay()
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
setNeedsDisplay()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
super.touchesCancelled(touches!, with: event)
setNeedsDisplay()
}
}