├── .gitignore
├── .swift-version
├── LICENSE
├── README-Chinese.md
├── README.md
├── ScreenShots
├── page1.jpg
├── page10.jpg
├── page11.jpg
├── page2.jpg
├── page3.jpg
├── page4.jpg
├── page5.jpg
├── page6.jpg
├── page7.jpg
├── page8.jpg
└── page9.jpg
├── Source
├── LBXPermissions.swift
├── LBXScanLineAnimation.swift
├── LBXScanNetAnimation.swift
├── LBXScanView.swift
├── LBXScanViewController.swift
├── LBXScanViewStyle.swift
└── LBXScanWrapper.swift
├── SwiftScanner
├── Info.plist
└── SwiftScanner.h
├── swiftScan.podspec
├── swiftScan.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── SwiftScanner.xcscheme
└── swiftScan
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── CodeScan.bundle
├── device_scan@2x.png
├── qrcode_Scan_weixin_Line@2x.png
├── qrcode_scan_btn_flash_down@2x.png
├── qrcode_scan_btn_flash_nor@2x.png
├── qrcode_scan_btn_myqrcode_down@2x.png
├── qrcode_scan_btn_myqrcode_nor@2x.png
├── qrcode_scan_btn_photo_down@2x.png
├── qrcode_scan_btn_photo_nor@2x.png
├── qrcode_scan_btn_scan_off@2x.png
├── qrcode_scan_full_net.png
├── qrcode_scan_light_green@2x.png
├── qrcode_scan_part_net.png
├── qrcode_scan_titlebar_back_nor@2x.png
└── qrcode_scan_titlebar_back_pressed@2x.png
├── Info.plist
├── MainTableViewController.swift
├── MyCodeViewController.swift
├── QQScanViewController.swift
├── ScanResultController.swift
├── ScanResultController.xib
├── ViewController.swift
├── logo.JPG
└── zh-Hans.lproj
├── LaunchScreen.strings
└── Main.strings
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | # Pods/
27 |
28 | # Carthage
29 | #
30 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
31 | # Carthage/Checkouts
32 |
33 | Carthage/Build
34 | swiftScan/.DS_Store
35 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.0
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README-Chinese.md:
--------------------------------------------------------------------------------
1 |
2 | # iOS 二维码、条形码 Swift 版本
3 |
4 |
5 | ### Objective-c版本: **[LBXScan](https://github.com/MxABC/LBXScan)**
6 |
7 |
8 |
9 | ## 介绍
10 | **swift封装系统自带扫码及识别图片功能**
11 | - 扫码界面效果封装
12 | - 二维码和条形码识别及生成
13 | - 相册获取图片后识别(测试效果不好...)
14 |
15 | **模仿其他app**
16 | - 模仿QQ扫码界面
17 | - 支付宝扫码框效果
18 | - 微信扫码框效果
19 |
20 | **其他设置参数自定义效果**
21 |
22 | - 扫码框周围区域背景色可设置
23 | - 扫码框颜色可也设置
24 | - 扫码框4个角的颜色可设置、大小可设置
25 | - 可设置只识别扫码框内的图像区域
26 | - 可设置扫码成功后,获取当前图片
27 | - 根据扫码结果,截取码的部分图像(在模仿qq扫码界面,扫码成功后可看到)
28 | - 动画效果选择: 线条上下移动、网格形式移动、中间线条不移动(一般扫码条形码的效果).
29 |
30 |
31 |
32 |
33 | ### CocoaPods安装
34 |
35 |
36 |
37 | ```ruby
38 | source 'https://github.com/CocoaPods/Specs.git'
39 | platform :ios, '8.0'
40 | use_frameworks!
41 | pod 'swiftScan', '~> 1.1.2'
42 | ```
43 |
44 |
45 | ### 手动安装
46 | 下载后将Source文件夹copy到工程即可
47 |
48 |
49 | ### 版本
50 | #### v1.0.9
51 | swift3.0
52 | #### v1.0.8
53 | 修改适应cocoapods安装后,编译报错bug
54 |
55 |
56 | ## 界面效果
57 |
58 | (加载速度慢,可刷新网页)
59 |
60 | 
61 | 
62 | 
63 | 
64 | 
65 | 
66 | 
67 | 
68 | 
69 | 
70 | 
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # iOS qrCode、barCode Swift Version
3 |
4 | [](https://developer.apple.com/iphone/index.action)
5 | [](https://en.wikipedia.org/wiki/swift)
7 | [](http://mit-license.org)
8 |
9 |
10 |
11 | ### Objective-c Version: **[LBXScan](https://github.com/MxABC/LBXScan)**
12 |
13 | ### [中文介绍](https://github.com/MxABC/swiftScan/blob/master/README-Chinese.md)
14 |
15 |
16 | ## Introduce
17 | #### Swift: The packaging system API comes with scan code and image recognition function
18 |
19 | - scan code interface
20 | - QR code and bar code recognition and generation
21 | - image recognition from the Album (Test results are not good)
22 |
23 | #### **Imitate other app**
24 |
25 | 1、 QQ scan code interface
26 | 2、Alipay scan code interface
27 | 3、Wechat scan code interface
28 |
29 | #### **Other settings parameters custom effects**
30 | - The background color can be set around the scan frame
31 | - Scan code frame color can also be set
32 | - Scan code box 4 corners of the color can be set, the size can be set
33 | - Can only be set to identify the scan code box in the image area
34 | - Scan code can be set to get the current picture
35 | - According to the results of the scan code, can intercept part of the image
36 | - Animation options: Line up and down、Grid form movement、Middle line not moving(use for bar code scanning commonly)
37 |
38 |
39 |
40 | ### Installation with CocoaPods
41 |
42 |
43 |
44 | ```ruby
45 | platform :ios, '8.0'
46 | use_frameworks!
47 | pod 'swiftScan', :git => 'https://github.com/MxABC/swiftScan.git'
48 | ```
49 |
50 |
51 | ### manually
52 | download and copy the Source folder to your project
53 |
54 |
55 |
56 | ## View effect
57 |
58 |
59 | 
60 | 
61 | 
62 | 
63 | 
64 | 
65 | 
66 | 
67 | 
68 | 
69 | 
70 |
--------------------------------------------------------------------------------
/ScreenShots/page1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page1.jpg
--------------------------------------------------------------------------------
/ScreenShots/page10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page10.jpg
--------------------------------------------------------------------------------
/ScreenShots/page11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page11.jpg
--------------------------------------------------------------------------------
/ScreenShots/page2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page2.jpg
--------------------------------------------------------------------------------
/ScreenShots/page3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page3.jpg
--------------------------------------------------------------------------------
/ScreenShots/page4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page4.jpg
--------------------------------------------------------------------------------
/ScreenShots/page5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page5.jpg
--------------------------------------------------------------------------------
/ScreenShots/page6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page6.jpg
--------------------------------------------------------------------------------
/ScreenShots/page7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page7.jpg
--------------------------------------------------------------------------------
/ScreenShots/page8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page8.jpg
--------------------------------------------------------------------------------
/ScreenShots/page9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/ScreenShots/page9.jpg
--------------------------------------------------------------------------------
/Source/LBXPermissions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXPermissions.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/15.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AVFoundation
11 | import Photos
12 | import AssetsLibrary
13 |
14 |
15 |
16 | class LBXPermissions: NSObject {
17 |
18 | //MARK: ----获取相册权限
19 | static func authorizePhotoWith(comletion: @escaping (Bool) -> Void) {
20 | let granted = PHPhotoLibrary.authorizationStatus()
21 | switch granted {
22 | case PHAuthorizationStatus.authorized:
23 | comletion(true)
24 | case PHAuthorizationStatus.denied, PHAuthorizationStatus.restricted:
25 | comletion(false)
26 | case PHAuthorizationStatus.notDetermined:
27 | PHPhotoLibrary.requestAuthorization({ status in
28 | DispatchQueue.main.async {
29 | comletion(status == PHAuthorizationStatus.authorized)
30 | }
31 | })
32 | case .limited:
33 | comletion(true)
34 | @unknown default:
35 | comletion(false)
36 | }
37 | }
38 |
39 | //MARK: ---相机权限
40 | static func authorizeCameraWith(completion: @escaping (Bool) -> Void) {
41 | let granted = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
42 | switch granted {
43 | case .authorized:
44 | completion(true)
45 | case .denied:
46 | completion(false)
47 | case .restricted:
48 | completion(false)
49 | case .notDetermined:
50 | AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted: Bool) in
51 | DispatchQueue.main.async {
52 | completion(granted)
53 | }
54 | })
55 | @unknown default:
56 | completion(false)
57 | }
58 | }
59 |
60 | //MARK: 跳转到APP系统设置权限界面
61 | static func jumpToSystemPrivacySetting() {
62 | guard let appSetting = URL(string: UIApplication.openSettingsURLString) else {
63 | return
64 | }
65 | if #available(iOS 10, *) {
66 | UIApplication.shared.open(appSetting, options: [:], completionHandler: nil)
67 | } else {
68 | UIApplication.shared.openURL(appSetting)
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Source/LBXScanLineAnimation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanLineAnimation.swift
3 | // swiftScan
4 | //
5 | // Created by lbxia on 15/12/9.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class LBXScanLineAnimation: UIImageView {
12 |
13 | var isAnimationing = false
14 | var animationRect = CGRect.zero
15 |
16 | func startAnimatingWithRect(animationRect: CGRect, parentView: UIView, image: UIImage?) {
17 | self.image = image
18 | self.animationRect = animationRect
19 | parentView.addSubview(self)
20 |
21 | isHidden = false
22 | isAnimationing = true
23 | if image != nil {
24 | stepAnimation()
25 | }
26 | }
27 |
28 | @objc func stepAnimation() {
29 | guard isAnimationing else {
30 | return
31 | }
32 | var frame = animationRect
33 | let hImg = image!.size.height * animationRect.size.width / image!.size.width
34 |
35 | frame.origin.y -= hImg
36 | frame.size.height = hImg
37 | self.frame = frame
38 | alpha = 0.0
39 |
40 | UIView.animate(withDuration: 1.4, animations: {
41 | self.alpha = 1.0
42 | var frame = self.animationRect
43 | let hImg = self.image!.size.height * self.animationRect.size.width / self.image!.size.width
44 | frame.origin.y += (frame.size.height - hImg)
45 | frame.size.height = hImg
46 | self.frame = frame
47 | }, completion: { _ in
48 | self.perform(#selector(LBXScanLineAnimation.stepAnimation), with: nil, afterDelay: 0.3)
49 | })
50 | }
51 |
52 | func stopStepAnimating() {
53 | isHidden = true
54 | isAnimationing = false
55 | }
56 |
57 | public static func instance() -> LBXScanLineAnimation {
58 | return LBXScanLineAnimation()
59 | }
60 |
61 | deinit {
62 | stopStepAnimating()
63 | }
64 |
65 | }
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Source/LBXScanNetAnimation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanNetAnimation.swift
3 | // swiftScan
4 | //
5 | // Created by lbxia on 15/12/9.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class LBXScanNetAnimation: UIImageView {
12 |
13 | var isAnimationing = false
14 | var animationRect = CGRect.zero
15 |
16 | public static func instance() -> LBXScanNetAnimation {
17 | return LBXScanNetAnimation()
18 | }
19 |
20 | func startAnimatingWithRect(animationRect: CGRect, parentView: UIView, image: UIImage?) {
21 | self.image = image
22 | self.animationRect = animationRect
23 | parentView.addSubview(self)
24 |
25 | isHidden = false
26 |
27 | isAnimationing = true
28 |
29 | if image != nil {
30 | stepAnimation()
31 | }
32 | }
33 |
34 | @objc func stepAnimation() {
35 | guard isAnimationing else {
36 | return
37 | }
38 | var frame = animationRect
39 |
40 | let hImg = image!.size.height * animationRect.size.width / image!.size.width
41 |
42 | frame.origin.y -= hImg
43 | frame.size.height = hImg
44 | self.frame = frame
45 |
46 | alpha = 0.0
47 |
48 | UIView.animate(withDuration: 1.2, animations: {
49 | self.alpha = 1.0
50 |
51 | var frame = self.animationRect
52 | let hImg = self.image!.size.height * self.animationRect.size.width / self.image!.size.width
53 |
54 | frame.origin.y += (frame.size.height - hImg)
55 | frame.size.height = hImg
56 |
57 | self.frame = frame
58 |
59 | }, completion: { _ in
60 | self.perform(#selector(LBXScanNetAnimation.stepAnimation), with: nil, afterDelay: 0.3)
61 | })
62 | }
63 |
64 | func stopStepAnimating() {
65 | isHidden = true
66 | isAnimationing = false
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Source/LBXScanView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanView.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/8.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class LBXScanView: UIView {
12 |
13 | // 扫码区域各种参数
14 | var viewStyle = LBXScanViewStyle()
15 |
16 | // 扫码区域
17 | var scanRetangleRect = CGRect.zero
18 |
19 | // 线条扫码动画封装
20 | var scanLineAnimation: LBXScanLineAnimation?
21 |
22 | // 网格扫码动画封装
23 | var scanNetAnimation: LBXScanNetAnimation?
24 |
25 | // 线条在中间位置,不移动
26 | var scanLineStill: UIImageView?
27 |
28 | // 启动相机时 菊花等待
29 | var activityView: UIActivityIndicatorView?
30 |
31 | // 启动相机中的提示文字
32 | var labelReadying: UILabel?
33 |
34 | // 记录动画状态
35 | var isAnimationing = false
36 |
37 | /**
38 | 初始化扫描界面
39 | - parameter frame: 界面大小,一般为视频显示区域
40 | - parameter vstyle: 界面效果参数
41 |
42 | - returns: instancetype
43 | */
44 | public init(frame: CGRect, vstyle: LBXScanViewStyle) {
45 | viewStyle = vstyle
46 |
47 | switch viewStyle.anmiationStyle {
48 | case LBXScanViewAnimationStyle.LineMove:
49 | scanLineAnimation = LBXScanLineAnimation.instance()
50 | case LBXScanViewAnimationStyle.NetGrid:
51 | scanNetAnimation = LBXScanNetAnimation.instance()
52 | case LBXScanViewAnimationStyle.LineStill:
53 | scanLineStill = UIImageView()
54 | scanLineStill?.image = viewStyle.animationImage
55 | default:
56 | break
57 | }
58 |
59 | var frameTmp = frame
60 | frameTmp.origin = CGPoint.zero
61 |
62 | super.init(frame: frameTmp)
63 |
64 | backgroundColor = UIColor.clear
65 | }
66 |
67 | override init(frame: CGRect) {
68 | var frameTmp = frame
69 | frameTmp.origin = CGPoint.zero
70 |
71 | super.init(frame: frameTmp)
72 |
73 | backgroundColor = UIColor.clear
74 | }
75 |
76 | public required init?(coder aDecoder: NSCoder) {
77 | self.init()
78 | }
79 |
80 | deinit {
81 | if scanLineAnimation != nil {
82 | scanLineAnimation!.stopStepAnimating()
83 | }
84 | if scanNetAnimation != nil {
85 | scanNetAnimation!.stopStepAnimating()
86 | }
87 | }
88 |
89 |
90 | // 开始扫描动画
91 | func startScanAnimation() {
92 | guard !isAnimationing else {
93 | return
94 | }
95 | isAnimationing = true
96 |
97 | let cropRect = getScanRectForAnimation()
98 |
99 | switch viewStyle.anmiationStyle {
100 | case .LineMove:
101 | scanLineAnimation?.startAnimatingWithRect(animationRect: cropRect,
102 | parentView: self,
103 | image: viewStyle.animationImage)
104 | case .NetGrid:
105 | scanNetAnimation?.startAnimatingWithRect(animationRect: cropRect,
106 | parentView: self,
107 | image: viewStyle.animationImage)
108 | case .LineStill:
109 | let stillRect = CGRect(x: cropRect.origin.x + 20,
110 | y: cropRect.origin.y + cropRect.size.height / 2,
111 | width: cropRect.size.width - 40,
112 | height: 2)
113 | scanLineStill?.frame = stillRect
114 |
115 | addSubview(scanLineStill!)
116 | scanLineStill?.isHidden = false
117 | default: break
118 | }
119 | }
120 |
121 | // 开始扫描动画
122 | func stopScanAnimation() {
123 | isAnimationing = false
124 | switch viewStyle.anmiationStyle {
125 | case .LineMove:
126 | scanLineAnimation?.stopStepAnimating()
127 | case .NetGrid:
128 | scanNetAnimation?.stopStepAnimating()
129 | case .LineStill:
130 | scanLineStill?.isHidden = true
131 | default: break
132 | }
133 | }
134 |
135 | // Only override drawRect: if you perform custom drawing.
136 | // An empty implementation adversely affects performance during animation.
137 | open override func draw(_ rect: CGRect) {
138 | drawScanRect()
139 | }
140 |
141 | //MARK: ----- 绘制扫码效果-----
142 | func drawScanRect() {
143 | let XRetangleLeft = viewStyle.xScanRetangleOffset
144 | var sizeRetangle = CGSize(width: frame.size.width - XRetangleLeft * 2.0, height: frame.size.width - XRetangleLeft * 2.0)
145 |
146 | if viewStyle.whRatio != 1.0 {
147 | let w = sizeRetangle.width
148 | var h = w / viewStyle.whRatio
149 | h = CGFloat(Int(h))
150 | sizeRetangle = CGSize(width: w, height: h)
151 | }
152 |
153 | // 扫码区域Y轴最小坐标
154 | let YMinRetangle = frame.size.height / 2.0 - sizeRetangle.height / 2.0 - viewStyle.centerUpOffset
155 | let YMaxRetangle = YMinRetangle + sizeRetangle.height
156 | let XRetangleRight = frame.size.width - XRetangleLeft
157 |
158 | guard let context = UIGraphicsGetCurrentContext() else {
159 | return
160 | }
161 |
162 | // 非扫码区域半透明
163 | // 设置非识别区域颜色
164 | context.setFillColor(viewStyle.color_NotRecoginitonArea.cgColor)
165 | // 填充矩形
166 | // 扫码区域上面填充
167 | var rect = CGRect(x: 0, y: 0, width: frame.size.width, height: YMinRetangle)
168 | context.fill(rect)
169 |
170 | // 扫码区域左边填充
171 | rect = CGRect(x: 0, y: YMinRetangle, width: XRetangleLeft, height: sizeRetangle.height)
172 | context.fill(rect)
173 |
174 | // 扫码区域右边填充
175 | rect = CGRect(x: XRetangleRight, y: YMinRetangle, width: XRetangleLeft, height: sizeRetangle.height)
176 | context.fill(rect)
177 |
178 | // 扫码区域下面填充
179 | rect = CGRect(x: 0, y: YMaxRetangle, width: frame.size.width, height: frame.size.height - YMaxRetangle)
180 | context.fill(rect)
181 | // 执行绘画
182 | context.strokePath()
183 |
184 | if viewStyle.isNeedShowRetangle {
185 | // 中间画矩形(正方形)
186 | context.setStrokeColor(viewStyle.colorRetangleLine.cgColor)
187 | context.setLineWidth(viewStyle.widthRetangleLine)
188 | context.addRect(CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height))
189 |
190 | // CGContextMoveToPoint(context, XRetangleLeft, YMinRetangle);
191 | // CGContextAddLineToPoint(context, XRetangleLeft+sizeRetangle.width, YMinRetangle);
192 |
193 | context.strokePath()
194 | }
195 |
196 | scanRetangleRect = CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
197 |
198 |
199 | // 画矩形框4格外围相框角
200 |
201 | // 相框角的宽度和高度
202 | let wAngle = viewStyle.photoframeAngleW
203 | let hAngle = viewStyle.photoframeAngleH
204 |
205 | // 4个角的 线的宽度
206 | let linewidthAngle = viewStyle.photoframeLineW // 经验参数:6和4
207 |
208 | // 画扫码矩形以及周边半透明黑色坐标参数
209 | var diffAngle = linewidthAngle / 3
210 | diffAngle = linewidthAngle / 2 // 框外面4个角,与框有缝隙
211 | diffAngle = linewidthAngle / 2 // 框4个角 在线上加4个角效果
212 | diffAngle = 0 // 与矩形框重合
213 |
214 | switch viewStyle.photoframeAngleStyle {
215 | case .Outer: diffAngle = linewidthAngle / 3 // 框外面4个角,与框紧密联系在一起
216 | case .On: diffAngle = 0
217 | case .Inner: diffAngle = -viewStyle.photoframeLineW / 2
218 | }
219 |
220 | context.setStrokeColor(viewStyle.colorAngle.cgColor)
221 | context.setFillColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
222 |
223 | // Draw them with a 2.0 stroke width so they are a bit more visible.
224 | context.setLineWidth(linewidthAngle)
225 |
226 |
227 | //
228 | let leftX = XRetangleLeft - diffAngle
229 | let topY = YMinRetangle - diffAngle
230 | let rightX = XRetangleRight + diffAngle
231 | let bottomY = YMaxRetangle + diffAngle
232 |
233 | // 左上角水平线
234 | context.move(to: CGPoint(x: leftX - linewidthAngle / 2, y: topY))
235 | context.addLine(to: CGPoint(x: leftX + wAngle, y: topY))
236 |
237 | // 左上角垂直线
238 | context.move(to: CGPoint(x: leftX, y: topY - linewidthAngle / 2))
239 | context.addLine(to: CGPoint(x: leftX, y: topY + hAngle))
240 |
241 | // 左下角水平线
242 | context.move(to: CGPoint(x: leftX - linewidthAngle / 2, y: bottomY))
243 | context.addLine(to: CGPoint(x: leftX + wAngle, y: bottomY))
244 |
245 | // 左下角垂直线
246 | context.move(to: CGPoint(x: leftX, y: bottomY + linewidthAngle / 2))
247 | context.addLine(to: CGPoint(x: leftX, y: bottomY - hAngle))
248 |
249 | // 右上角水平线
250 | context.move(to: CGPoint(x: rightX + linewidthAngle / 2, y: topY))
251 | context.addLine(to: CGPoint(x: rightX - wAngle, y: topY))
252 |
253 | // 右上角垂直线
254 | context.move(to: CGPoint(x: rightX, y: topY - linewidthAngle / 2))
255 | context.addLine(to: CGPoint(x: rightX, y: topY + hAngle))
256 |
257 | // 右下角水平线
258 | context.move(to: CGPoint(x: rightX + linewidthAngle / 2, y: bottomY))
259 | context.addLine(to: CGPoint(x: rightX - wAngle, y: bottomY))
260 |
261 | // 右下角垂直线
262 | context.move(to: CGPoint(x: rightX, y: bottomY + linewidthAngle / 2))
263 | context.addLine(to: CGPoint(x: rightX, y: bottomY - hAngle))
264 |
265 | context.strokePath()
266 | }
267 |
268 | // 根据矩形区域,获取识别区域
269 | static func getScanRectWithPreView(preView: UIView, style: LBXScanViewStyle) -> CGRect {
270 | let XRetangleLeft = style.xScanRetangleOffset
271 | let width = preView.frame.size.width - XRetangleLeft * 2
272 | let height = width
273 | var sizeRetangle = CGSize(width: width, height: height)
274 |
275 | if style.whRatio != 1 {
276 | let w = sizeRetangle.width
277 | var h = w / style.whRatio
278 |
279 | let hInt: Int = Int(h)
280 | h = CGFloat(hInt)
281 |
282 | sizeRetangle = CGSize(width: w, height: h)
283 | }
284 |
285 | // 扫码区域Y轴最小坐标
286 | let YMinRetangle = preView.frame.size.height / 2.0 - sizeRetangle.height / 2.0 - style.centerUpOffset
287 | // 扫码区域坐标
288 | let cropRect = CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
289 |
290 | // 计算兴趣区域
291 | var rectOfInterest: CGRect
292 |
293 | // ref:http://www.cocoachina.com/ios/20141225/10763.html
294 | let size = preView.bounds.size
295 | let p1 = size.height / size.width
296 |
297 | let p2: CGFloat = 1920.0 / 1080.0 // 使用了1080p的图像输出
298 | if p1 < p2 {
299 | let fixHeight = size.width * 1920.0 / 1080.0
300 | let fixPadding = (fixHeight - size.height) / 2
301 | rectOfInterest = CGRect(x: (cropRect.origin.y + fixPadding) / fixHeight,
302 | y: cropRect.origin.x / size.width,
303 | width: cropRect.size.height / fixHeight,
304 | height: cropRect.size.width / size.width)
305 |
306 | } else {
307 | let fixWidth = size.height * 1080.0 / 1920.0
308 | let fixPadding = (fixWidth - size.width) / 2
309 | rectOfInterest = CGRect(x: cropRect.origin.y / size.height,
310 | y: (cropRect.origin.x + fixPadding) / fixWidth,
311 | width: cropRect.size.height / size.height,
312 | height: cropRect.size.width / fixWidth)
313 | }
314 |
315 | return rectOfInterest
316 | }
317 |
318 | func getRetangeSize() -> CGSize {
319 | let XRetangleLeft = viewStyle.xScanRetangleOffset
320 | var sizeRetangle = CGSize(width: frame.size.width - XRetangleLeft * 2, height: frame.size.width - XRetangleLeft * 2)
321 |
322 | let w = sizeRetangle.width
323 | var h = w / viewStyle.whRatio
324 | h = CGFloat(Int(h))
325 | sizeRetangle = CGSize(width: w, height: h)
326 |
327 | return sizeRetangle
328 | }
329 |
330 | func deviceStartReadying(readyStr: String) {
331 | let XRetangleLeft = viewStyle.xScanRetangleOffset
332 | let sizeRetangle = getRetangeSize()
333 |
334 | // 扫码区域Y轴最小坐标
335 | let YMinRetangle = frame.size.height / 2.0 - sizeRetangle.height / 2.0 - viewStyle.centerUpOffset
336 |
337 | // 设备启动状态提示
338 | if activityView == nil {
339 | activityView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
340 |
341 | activityView?.center = CGPoint(x: XRetangleLeft + sizeRetangle.width / 2 - 50, y: YMinRetangle + sizeRetangle.height / 2)
342 | activityView?.style = UIActivityIndicatorView.Style.whiteLarge
343 |
344 | addSubview(activityView!)
345 |
346 | let labelReadyRect = CGRect(x: activityView!.frame.origin.x + activityView!.frame.size.width + 10,
347 | y: activityView!.frame.origin.y,
348 | width: 100,
349 | height: 30)
350 | labelReadying = UILabel(frame: labelReadyRect)
351 | labelReadying?.text = readyStr
352 | labelReadying?.backgroundColor = UIColor.clear
353 | labelReadying?.textColor = UIColor.white
354 | labelReadying?.font = UIFont.systemFont(ofSize: 18.0)
355 | addSubview(labelReadying!)
356 | }
357 |
358 | addSubview(labelReadying!)
359 | activityView?.startAnimating()
360 | }
361 |
362 | func deviceStopReadying() {
363 | if activityView != nil {
364 | activityView?.stopAnimating()
365 | activityView?.removeFromSuperview()
366 | labelReadying?.removeFromSuperview()
367 |
368 | activityView = nil
369 | labelReadying = nil
370 | }
371 | }
372 |
373 | }
374 |
375 | //MARK: - 公开方法
376 | public extension LBXScanView {
377 |
378 | /// 获取扫描动画的Rect
379 | func getScanRectForAnimation() -> CGRect {
380 | let XRetangleLeft = viewStyle.xScanRetangleOffset
381 | var sizeRetangle = CGSize(width: frame.size.width - XRetangleLeft * 2,
382 | height: frame.size.width - XRetangleLeft * 2)
383 |
384 | if viewStyle.whRatio != 1 {
385 | let w = sizeRetangle.width
386 | let h = w / viewStyle.whRatio
387 | sizeRetangle = CGSize(width: w, height: CGFloat(Int(h)))
388 | }
389 |
390 | // 扫码区域Y轴最小坐标
391 | let YMinRetangle = frame.size.height / 2.0 - sizeRetangle.height / 2.0 - viewStyle.centerUpOffset
392 | // 扫码区域坐标
393 | let cropRect = CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
394 |
395 | return cropRect
396 | }
397 |
398 | }
399 |
--------------------------------------------------------------------------------
/Source/LBXScanViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanViewController.swift
3 | // swiftScan
4 | //
5 | // Created by lbxia on 15/12/8.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Foundation
11 | import AVFoundation
12 |
13 | public protocol LBXScanViewControllerDelegate: class {
14 | func scanFinished(scanResult: LBXScanResult, error: String?)
15 | }
16 |
17 | public protocol QRRectDelegate {
18 | func drawwed()
19 | }
20 |
21 | open class LBXScanViewController: UIViewController {
22 |
23 | // 返回扫码结果,也可以通过继承本控制器,改写该handleCodeResult方法即可
24 | open weak var scanResultDelegate: LBXScanViewControllerDelegate?
25 |
26 | open var delegate: QRRectDelegate?
27 |
28 | open var scanObj: LBXScanWrapper?
29 |
30 | open var scanStyle: LBXScanViewStyle? = LBXScanViewStyle()
31 |
32 | open var qRScanView: LBXScanView?
33 |
34 | // 启动区域识别功能
35 | open var isOpenInterestRect = false
36 |
37 | //连续扫码
38 | open var isSupportContinuous = false;
39 |
40 | // 识别码的类型
41 | public var arrayCodeType: [AVMetadataObject.ObjectType]?
42 |
43 | // 是否需要识别后的当前图像
44 | public var isNeedCodeImage = false
45 |
46 | // 相机启动提示文字
47 | public var readyString: String! = "loading"
48 |
49 | open override func viewDidLoad() {
50 | super.viewDidLoad()
51 |
52 | // Do any additional setup after loading the view.
53 |
54 | // [self.view addSubview:_qRScanView];
55 | view.backgroundColor = UIColor.black
56 | edgesForExtendedLayout = UIRectEdge(rawValue: 0)
57 | }
58 |
59 | open func setNeedCodeImage(needCodeImg: Bool) {
60 | isNeedCodeImage = needCodeImg
61 | }
62 |
63 | // 设置框内识别
64 | open func setOpenInterestRect(isOpen: Bool) {
65 | isOpenInterestRect = isOpen
66 | }
67 |
68 | open override func viewDidAppear(_ animated: Bool) {
69 | super.viewDidAppear(animated)
70 | drawScanView()
71 | perform(#selector(LBXScanViewController.startScan), with: nil, afterDelay: 0.3)
72 | }
73 |
74 | @objc open func startScan() {
75 | if scanObj == nil {
76 | var cropRect = CGRect.zero
77 | if isOpenInterestRect {
78 | cropRect = LBXScanView.getScanRectWithPreView(preView: view, style: scanStyle!)
79 | }
80 |
81 | // 指定识别几种码
82 | if arrayCodeType == nil {
83 | arrayCodeType = [AVMetadataObject.ObjectType.qr as NSString,
84 | AVMetadataObject.ObjectType.ean13 as NSString,
85 | AVMetadataObject.ObjectType.code128 as NSString] as [AVMetadataObject.ObjectType]
86 | }
87 |
88 | scanObj = LBXScanWrapper(videoPreView: view,
89 | objType: arrayCodeType!,
90 | isCaptureImg: isNeedCodeImage,
91 | cropRect: cropRect,
92 | success: { [weak self] (arrayResult) -> Void in
93 | guard let strongSelf = self else {
94 | return
95 | }
96 | if !strongSelf.isSupportContinuous {
97 | // 停止扫描动画
98 | strongSelf.qRScanView?.stopScanAnimation()
99 | }
100 | strongSelf.handleCodeResult(arrayResult: arrayResult)
101 | })
102 | }
103 |
104 | scanObj?.supportContinuous = isSupportContinuous;
105 |
106 | // 结束相机等待提示
107 | qRScanView?.deviceStopReadying()
108 |
109 | // 开始扫描动画
110 | qRScanView?.startScanAnimation()
111 |
112 | // 相机运行
113 | scanObj?.start()
114 | }
115 |
116 | open func drawScanView() {
117 | if qRScanView == nil {
118 | qRScanView = LBXScanView(frame: view.frame, vstyle: scanStyle!)
119 | view.addSubview(qRScanView!)
120 | delegate?.drawwed()
121 | }
122 | qRScanView?.deviceStartReadying(readyStr: readyString)
123 | }
124 |
125 |
126 | /**
127 | 处理扫码结果,如果是继承本控制器的,可以重写该方法,作出相应地处理,或者设置delegate作出相应处理
128 | */
129 | open func handleCodeResult(arrayResult: [LBXScanResult]) {
130 | guard let delegate = scanResultDelegate else {
131 | fatalError("you must set scanResultDelegate or override this method without super keyword")
132 | }
133 |
134 | if !isSupportContinuous {
135 | navigationController?.popViewController(animated: true)
136 |
137 | }
138 |
139 | if let result = arrayResult.first {
140 | delegate.scanFinished(scanResult: result, error: nil)
141 | } else {
142 | let result = LBXScanResult(str: nil, img: nil, barCodeType: nil, corner: nil)
143 | delegate.scanFinished(scanResult: result, error: "no scan result")
144 | }
145 | }
146 |
147 | open override func viewWillDisappear(_ animated: Bool) {
148 | NSObject.cancelPreviousPerformRequests(withTarget: self)
149 | qRScanView?.stopScanAnimation()
150 | scanObj?.stop()
151 | }
152 |
153 | @objc open func openPhotoAlbum() {
154 | LBXPermissions.authorizePhotoWith { [weak self] _ in
155 | let picker = UIImagePickerController()
156 | picker.sourceType = UIImagePickerController.SourceType.photoLibrary
157 | picker.delegate = self
158 | picker.allowsEditing = true
159 | self?.present(picker, animated: true, completion: nil)
160 | }
161 | }
162 | }
163 |
164 | //MARK: - 图片选择代理方法
165 | extension LBXScanViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
166 |
167 | //MARK: -----相册选择图片识别二维码 (条形码没有找到系统方法)
168 | public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
169 | picker.dismiss(animated: true, completion: nil)
170 |
171 | let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
172 | let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
173 | guard let image = editedImage ?? originalImage else {
174 | showMsg(title: nil, message: NSLocalizedString("Identify failed", comment: "Identify failed"))
175 | return
176 | }
177 | let arrayResult = LBXScanWrapper.recognizeQRImage(image: image)
178 | if !arrayResult.isEmpty {
179 | handleCodeResult(arrayResult: arrayResult)
180 | }
181 | }
182 |
183 | }
184 |
185 | //MARK: - 私有方法
186 | private extension LBXScanViewController {
187 |
188 | func showMsg(title: String?, message: String?) {
189 | let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
190 | let alertAction = UIAlertAction(title: NSLocalizedString("OK", comment: "OK"), style: .default, handler: nil)
191 | alertController.addAction(alertAction)
192 | present(alertController, animated: true, completion: nil)
193 | }
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/Source/LBXScanViewStyle.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanViewStyle.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/8.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// 扫码区域动画效果
12 | public enum LBXScanViewAnimationStyle {
13 | case LineMove // 线条上下移动
14 | case NetGrid // 网格
15 | case LineStill // 线条停止在扫码区域中央
16 | case None // 无动画
17 | }
18 |
19 | /// 扫码区域4个角位置类型
20 | public enum LBXScanViewPhotoframeAngleStyle {
21 | case Inner // 内嵌,一般不显示矩形框情况下
22 | case Outer // 外嵌,包围在矩形框的4个角
23 | case On // 在矩形框的4个角上,覆盖
24 | }
25 |
26 |
27 | public struct LBXScanViewStyle {
28 |
29 | // MARK: - 中心位置矩形框
30 |
31 | /// 是否需要绘制扫码矩形框,默认YES
32 | public var isNeedShowRetangle = true
33 |
34 | /// 默认扫码区域为正方形,如果扫码区域不是正方形,设置宽高比
35 | public var whRatio: CGFloat = 1.0
36 |
37 | /// 矩形框(视频显示透明区)域向上移动偏移量,0表示扫码透明区域在当前视图中心位置,如果负值表示扫码区域下移
38 | public var centerUpOffset: CGFloat = 44
39 |
40 | /// 矩形框(视频显示透明区)域离界面左边及右边距离,默认60
41 | public var xScanRetangleOffset: CGFloat = 60
42 |
43 | /// 矩形框线条颜色,默认白色
44 | public var colorRetangleLine = UIColor.white
45 |
46 | /// 矩形框线条宽度,默认1
47 | public var widthRetangleLine: CGFloat = 1.0
48 |
49 | //MARK: - 矩形框(扫码区域)周围4个角
50 |
51 | /// 扫码区域的4个角类型
52 | public var photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Outer
53 |
54 | /// 4个角的颜色
55 | public var colorAngle = UIColor(red: 0.0, green: 167.0 / 255.0, blue: 231.0 / 255.0, alpha: 1.0)
56 |
57 | /// 扫码区域4个角的宽度和高度
58 | public var photoframeAngleW: CGFloat = 24.0
59 | public var photoframeAngleH: CGFloat = 24.0
60 |
61 | /// 扫码区域4个角的线条宽度,默认6,建议8到4之间
62 | public var photoframeLineW: CGFloat = 6
63 |
64 | //MARK: - 动画效果
65 |
66 | /// 扫码动画效果:线条或网格
67 | public var anmiationStyle = LBXScanViewAnimationStyle.LineMove
68 |
69 | /// 动画效果的图像,如线条或网格的图像
70 | public var animationImage: UIImage?
71 |
72 | //MARK: - 非识别区域颜色, 默认 RGBA (0,0,0,0.5),范围(0--1)
73 |
74 | public var color_NotRecoginitonArea = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
75 |
76 | public init() { }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/Source/LBXScanWrapper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LBXScanWrapper.swift
3 | // swiftScan
4 | //
5 | // Created by lbxia on 15/12/10.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AVFoundation
11 |
12 | public struct LBXScanResult {
13 |
14 | /// 码内容
15 | public var strScanned: String?
16 |
17 | /// 扫描图像
18 | public var imgScanned: UIImage?
19 |
20 | /// 码的类型
21 | public var strBarCodeType: String?
22 |
23 | /// 码在图像中的位置
24 | public var arrayCorner: [AnyObject]?
25 |
26 | public init(str: String?, img: UIImage?, barCodeType: String?, corner: [AnyObject]?) {
27 | strScanned = str
28 | imgScanned = img
29 | strBarCodeType = barCodeType
30 | arrayCorner = corner
31 | }
32 | }
33 |
34 |
35 |
36 | open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate {
37 |
38 | let device = AVCaptureDevice.default(for: AVMediaType.video)
39 | var input: AVCaptureDeviceInput?
40 | var output: AVCaptureMetadataOutput
41 |
42 | let session = AVCaptureSession()
43 | var previewLayer: AVCaptureVideoPreviewLayer?
44 | var stillImageOutput: AVCaptureStillImageOutput
45 |
46 | // 存储返回结果
47 | var arrayResult = [LBXScanResult]()
48 |
49 | // 扫码结果返回block
50 | var successBlock: ([LBXScanResult]) -> Void
51 |
52 | // 是否需要拍照
53 | var isNeedCaptureImage: Bool
54 |
55 | // 当前扫码结果是否处理
56 | var isNeedScanResult = true
57 |
58 | //连续扫码
59 | var supportContinuous = false
60 |
61 |
62 | /**
63 | 初始化设备
64 | - parameter videoPreView: 视频显示UIView
65 | - parameter objType: 识别码的类型,缺省值 QR二维码
66 | - parameter isCaptureImg: 识别后是否采集当前照片
67 | - parameter cropRect: 识别区域
68 | - parameter success: 返回识别信息
69 | - returns:
70 | */
71 | init(videoPreView: UIView,
72 | objType: [AVMetadataObject.ObjectType] = [(AVMetadataObject.ObjectType.qr as NSString) as AVMetadataObject.ObjectType],
73 | isCaptureImg: Bool,
74 | cropRect: CGRect = .zero,
75 | success: @escaping (([LBXScanResult]) -> Void)) {
76 |
77 | successBlock = success
78 | output = AVCaptureMetadataOutput()
79 | isNeedCaptureImage = isCaptureImg
80 | stillImageOutput = AVCaptureStillImageOutput()
81 |
82 | super.init()
83 |
84 | guard let device = device else {
85 | return
86 | }
87 | do {
88 | input = try AVCaptureDeviceInput(device: device)
89 | } catch let error as NSError {
90 | print("AVCaptureDeviceInput(): \(error)")
91 | }
92 | guard let input = input else {
93 | return
94 | }
95 |
96 | if session.canAddInput(input) {
97 | session.addInput(input)
98 | }
99 |
100 | if session.canAddOutput(output) {
101 | session.addOutput(output)
102 | }
103 |
104 | if session.canAddOutput(stillImageOutput) {
105 | session.addOutput(stillImageOutput)
106 | }
107 |
108 | stillImageOutput.outputSettings = [AVVideoCodecJPEG: AVVideoCodecKey]
109 |
110 | session.sessionPreset = AVCaptureSession.Preset.high
111 |
112 | // 参数设置
113 | output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
114 |
115 | output.metadataObjectTypes = objType
116 |
117 | // output.metadataObjectTypes = [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]
118 |
119 | if !cropRect.equalTo(CGRect.zero) {
120 | // 启动相机后,直接修改该参数无效
121 | output.rectOfInterest = cropRect
122 | }
123 |
124 | previewLayer = AVCaptureVideoPreviewLayer(session: session)
125 | previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
126 |
127 | var frame: CGRect = videoPreView.frame
128 | frame.origin = CGPoint.zero
129 | previewLayer?.frame = frame
130 |
131 | videoPreView.layer.insertSublayer(previewLayer!, at: 0)
132 |
133 | if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(.continuousAutoFocus) {
134 | do {
135 | try input.device.lockForConfiguration()
136 | input.device.focusMode = AVCaptureDevice.FocusMode.continuousAutoFocus
137 | input.device.unlockForConfiguration()
138 | } catch let error as NSError {
139 | print("device.lockForConfiguration(): \(error)")
140 | }
141 | }
142 | }
143 |
144 | public func metadataOutput(_ output: AVCaptureMetadataOutput,
145 | didOutput metadataObjects: [AVMetadataObject],
146 | from connection: AVCaptureConnection) {
147 | captureOutput(output, didOutputMetadataObjects: metadataObjects, from: connection)
148 | }
149 |
150 | func start() {
151 | if !session.isRunning {
152 | isNeedScanResult = true
153 | session.startRunning()
154 | }
155 | }
156 |
157 | func stop() {
158 | if session.isRunning {
159 | isNeedScanResult = false
160 | session.stopRunning()
161 | }
162 | }
163 |
164 | open func captureOutput(_ captureOutput: AVCaptureOutput,
165 | didOutputMetadataObjects metadataObjects: [Any],
166 | from connection: AVCaptureConnection!) {
167 | guard isNeedScanResult else {
168 | // 上一帧处理中
169 | return
170 | }
171 | isNeedScanResult = false
172 |
173 | arrayResult.removeAll()
174 |
175 | // 识别扫码类型
176 | for current in metadataObjects {
177 | guard let code = current as? AVMetadataMachineReadableCodeObject else {
178 | continue
179 | }
180 |
181 | #if !targetEnvironment(simulator)
182 |
183 | arrayResult.append(LBXScanResult(str: code.stringValue,
184 | img: UIImage(),
185 | barCodeType: code.type.rawValue,
186 | corner: code.corners as [AnyObject]?))
187 | #endif
188 | }
189 |
190 | if arrayResult.isEmpty || supportContinuous {
191 | isNeedScanResult = true
192 | }
193 | if !arrayResult.isEmpty {
194 |
195 | if supportContinuous {
196 | successBlock(arrayResult)
197 | }
198 | else if isNeedCaptureImage {
199 | captureImage()
200 | } else {
201 | stop()
202 | successBlock(arrayResult)
203 | }
204 | }
205 | }
206 |
207 | //MARK: ----拍照
208 | open func captureImage() {
209 | guard let stillImageConnection = connectionWithMediaType(mediaType: AVMediaType.video as AVMediaType,
210 | connections: stillImageOutput.connections as [AnyObject]) else {
211 | return
212 | }
213 | stillImageOutput.captureStillImageAsynchronously(from: stillImageConnection, completionHandler: { (imageDataSampleBuffer, _) -> Void in
214 | self.stop()
215 | if let imageDataSampleBuffer = imageDataSampleBuffer,
216 | let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
217 |
218 | let scanImg = UIImage(data: imageData)
219 | for idx in 0 ... self.arrayResult.count - 1 {
220 | self.arrayResult[idx].imgScanned = scanImg
221 | }
222 | }
223 | self.successBlock(self.arrayResult)
224 | })
225 | }
226 |
227 | open func connectionWithMediaType(mediaType: AVMediaType, connections: [AnyObject]) -> AVCaptureConnection? {
228 | for connection in connections {
229 | guard let connectionTmp = connection as? AVCaptureConnection else {
230 | continue
231 | }
232 | for port in connectionTmp.inputPorts where port.mediaType == mediaType {
233 | return connectionTmp
234 | }
235 | }
236 | return nil
237 | }
238 |
239 |
240 | //MARK: 切换识别区域
241 |
242 | open func changeScanRect(cropRect: CGRect) {
243 | // 待测试,不知道是否有效
244 | stop()
245 | output.rectOfInterest = cropRect
246 | start()
247 | }
248 |
249 | //MARK: 切换识别码的类型
250 | open func changeScanType(objType: [AVMetadataObject.ObjectType]) {
251 | // 待测试中途修改是否有效
252 | output.metadataObjectTypes = objType
253 | }
254 |
255 | open func isGetFlash() -> Bool {
256 | return device != nil && device!.hasFlash && device!.hasTorch
257 | }
258 |
259 | /**
260 | 打开或关闭闪关灯
261 | - parameter torch: true:打开闪关灯 false:关闭闪光灯
262 | */
263 | open func setTorch(torch: Bool) {
264 | guard isGetFlash() else {
265 | return
266 | }
267 | do {
268 | try input?.device.lockForConfiguration()
269 | input?.device.torchMode = torch ? AVCaptureDevice.TorchMode.on : AVCaptureDevice.TorchMode.off
270 | input?.device.unlockForConfiguration()
271 | } catch let error as NSError {
272 | print("device.lockForConfiguration(): \(error)")
273 | }
274 | }
275 |
276 |
277 | /// 闪光灯打开或关闭
278 | open func changeTorch() {
279 | let torch = input?.device.torchMode == .off
280 | setTorch(torch: torch)
281 | }
282 |
283 | //MARK: ------获取系统默认支持的码的类型
284 | static func defaultMetaDataObjectTypes() -> [AVMetadataObject.ObjectType] {
285 | var types =
286 | [
287 | AVMetadataObject.ObjectType.qr,
288 | AVMetadataObject.ObjectType.upce,
289 | AVMetadataObject.ObjectType.code39,
290 | AVMetadataObject.ObjectType.code39Mod43,
291 | AVMetadataObject.ObjectType.ean13,
292 | AVMetadataObject.ObjectType.ean8,
293 | AVMetadataObject.ObjectType.code93,
294 | AVMetadataObject.ObjectType.code128,
295 | AVMetadataObject.ObjectType.pdf417,
296 | AVMetadataObject.ObjectType.aztec,
297 | ]
298 | // if #available(iOS 8.0, *)
299 |
300 | types.append(AVMetadataObject.ObjectType.interleaved2of5)
301 | types.append(AVMetadataObject.ObjectType.itf14)
302 | types.append(AVMetadataObject.ObjectType.dataMatrix)
303 | return types
304 | }
305 |
306 | /**
307 | 识别二维码码图像
308 |
309 | - parameter image: 二维码图像
310 |
311 | - returns: 返回识别结果
312 | */
313 | public static func recognizeQRImage(image: UIImage) -> [LBXScanResult] {
314 | guard let cgImage = image.cgImage else {
315 | return []
316 | }
317 | let detector = CIDetector(ofType: CIDetectorTypeQRCode,
318 | context: nil,
319 | options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])!
320 | let img = CIImage(cgImage: cgImage)
321 | let features = detector.features(in: img, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
322 | return features.filter {
323 | $0.isKind(of: CIQRCodeFeature.self)
324 | }.map {
325 | $0 as! CIQRCodeFeature
326 | }.map {
327 | LBXScanResult(str: $0.messageString,
328 | img: image,
329 | barCodeType: AVMetadataObject.ObjectType.qr.rawValue,
330 | corner: nil)
331 | }
332 | }
333 |
334 |
335 | //MARK: -- - 生成二维码,背景色及二维码颜色设置
336 | public static func createCode(codeType: String, codeString: String, size: CGSize, qrColor: UIColor, bkColor: UIColor) -> UIImage? {
337 | let stringData = codeString.data(using: .utf8)
338 |
339 | // 系统自带能生成的码
340 | // CIAztecCodeGenerator
341 | // CICode128BarcodeGenerator
342 | // CIPDF417BarcodeGenerator
343 | // CIQRCodeGenerator
344 | let qrFilter = CIFilter(name: codeType)
345 | qrFilter?.setValue(stringData, forKey: "inputMessage")
346 | qrFilter?.setValue("H", forKey: "inputCorrectionLevel")
347 |
348 | // 上色
349 | let colorFilter = CIFilter(name: "CIFalseColor",
350 | parameters: [
351 | "inputImage": qrFilter!.outputImage!,
352 | "inputColor0": CIColor(cgColor: qrColor.cgColor),
353 | "inputColor1": CIColor(cgColor: bkColor.cgColor),
354 | ]
355 | )
356 |
357 | guard let qrImage = colorFilter?.outputImage,
358 | let cgImage = CIContext().createCGImage(qrImage, from: qrImage.extent) else {
359 | return nil
360 | }
361 |
362 | UIGraphicsBeginImageContext(size)
363 | let context = UIGraphicsGetCurrentContext()!
364 | context.interpolationQuality = CGInterpolationQuality.none
365 | context.scaleBy(x: 1.0, y: -1.0)
366 | context.draw(cgImage, in: context.boundingBoxOfClipPath)
367 | let codeImage = UIGraphicsGetImageFromCurrentImageContext()
368 | UIGraphicsEndImageContext()
369 |
370 | return codeImage
371 | }
372 |
373 | public static func createCode128(codeString: String, size: CGSize, qrColor: UIColor, bkColor: UIColor) -> UIImage? {
374 | let stringData = codeString.data(using: String.Encoding.utf8)
375 |
376 | // 系统自带能生成的码
377 | // CIAztecCodeGenerator 二维码
378 | // CICode128BarcodeGenerator 条形码
379 | // CIPDF417BarcodeGenerator
380 | // CIQRCodeGenerator 二维码
381 | let qrFilter = CIFilter(name: "CICode128BarcodeGenerator")
382 | qrFilter?.setDefaults()
383 | qrFilter?.setValue(stringData, forKey: "inputMessage")
384 |
385 | guard let outputImage = qrFilter?.outputImage else {
386 | return nil
387 | }
388 | let context = CIContext()
389 | guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else {
390 | return nil
391 | }
392 | let image = UIImage(cgImage: cgImage, scale: 1.0, orientation: UIImage.Orientation.up)
393 |
394 | // Resize without interpolating
395 | return resizeImage(image: image, quality: CGInterpolationQuality.none, rate: 20.0)
396 | }
397 |
398 |
399 | // 根据扫描结果,获取图像中得二维码区域图像(如果相机拍摄角度故意很倾斜,获取的图像效果很差)
400 | static func getConcreteCodeImage(srcCodeImage: UIImage, codeResult: LBXScanResult) -> UIImage? {
401 | let rect = getConcreteCodeRectFromImage(srcCodeImage: srcCodeImage, codeResult: codeResult)
402 | guard !rect.isEmpty, let img = imageByCroppingWithStyle(srcImg: srcCodeImage, rect: rect) else {
403 | return nil
404 | }
405 | return imageRotation(image: img, orientation: UIImage.Orientation.right)
406 | }
407 |
408 | // 根据二维码的区域截取二维码区域图像
409 | public static func getConcreteCodeImage(srcCodeImage: UIImage, rect: CGRect) -> UIImage? {
410 | guard !rect.isEmpty, let img = imageByCroppingWithStyle(srcImg: srcCodeImage, rect: rect) else {
411 | return nil
412 | }
413 | return imageRotation(image: img, orientation: UIImage.Orientation.right)
414 | }
415 |
416 | // 获取二维码的图像区域
417 | public static func getConcreteCodeRectFromImage(srcCodeImage: UIImage, codeResult: LBXScanResult) -> CGRect {
418 | guard let corner = codeResult.arrayCorner as? [[String: Float]], corner.count >= 4 else {
419 | return .zero
420 | }
421 |
422 | let dicTopLeft = corner[0]
423 | let dicTopRight = corner[1]
424 | let dicBottomRight = corner[2]
425 | let dicBottomLeft = corner[3]
426 |
427 | let xLeftTopRatio = dicTopLeft["X"]!
428 | let yLeftTopRatio = dicTopLeft["Y"]!
429 |
430 | let xRightTopRatio = dicTopRight["X"]!
431 | let yRightTopRatio = dicTopRight["Y"]!
432 |
433 | let xBottomRightRatio = dicBottomRight["X"]!
434 | let yBottomRightRatio = dicBottomRight["Y"]!
435 |
436 | let xLeftBottomRatio = dicBottomLeft["X"]!
437 | let yLeftBottomRatio = dicBottomLeft["Y"]!
438 |
439 | // 由于截图只能矩形,所以截图不规则四边形的最大外围
440 | let xMinLeft = CGFloat(min(xLeftTopRatio, xLeftBottomRatio))
441 | let xMaxRight = CGFloat(max(xRightTopRatio, xBottomRightRatio))
442 |
443 | let yMinTop = CGFloat(min(yLeftTopRatio, yRightTopRatio))
444 | let yMaxBottom = CGFloat(max(yLeftBottomRatio, yBottomRightRatio))
445 |
446 | let imgW = srcCodeImage.size.width
447 | let imgH = srcCodeImage.size.height
448 |
449 | // 宽高反过来计算
450 | return CGRect(x: xMinLeft * imgH,
451 | y: yMinTop * imgW,
452 | width: (xMaxRight - xMinLeft) * imgH,
453 | height: (yMaxBottom - yMinTop) * imgW)
454 | }
455 |
456 | //MARK: ----图像处理
457 |
458 | /**
459 |
460 | @brief 图像中间加logo图片
461 | @param srcImg 原图像
462 | @param LogoImage logo图像
463 | @param logoSize logo图像尺寸
464 | @return 加Logo的图像
465 | */
466 | public static func addImageLogo(srcImg: UIImage, logoImg: UIImage, logoSize: CGSize) -> UIImage {
467 | UIGraphicsBeginImageContext(srcImg.size)
468 | srcImg.draw(in: CGRect(x: 0, y: 0, width: srcImg.size.width, height: srcImg.size.height))
469 | let rect = CGRect(x: srcImg.size.width / 2 - logoSize.width / 2,
470 | y: srcImg.size.height / 2 - logoSize.height / 2,
471 | width: logoSize.width,
472 | height: logoSize.height)
473 | logoImg.draw(in: rect)
474 | let resultingImage = UIGraphicsGetImageFromCurrentImageContext()
475 | UIGraphicsEndImageContext()
476 | return resultingImage!
477 | }
478 |
479 | //图像缩放
480 | static func resizeImage(image: UIImage, quality: CGInterpolationQuality, rate: CGFloat) -> UIImage? {
481 | var resized: UIImage?
482 | let width = image.size.width * rate
483 | let height = image.size.height * rate
484 |
485 | UIGraphicsBeginImageContext(CGSize(width: width, height: height))
486 | let context = UIGraphicsGetCurrentContext()
487 | context?.interpolationQuality = quality
488 | image.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
489 |
490 | resized = UIGraphicsGetImageFromCurrentImageContext()
491 | UIGraphicsEndImageContext()
492 |
493 | return resized
494 | }
495 |
496 | // 图像裁剪
497 | static func imageByCroppingWithStyle(srcImg: UIImage, rect: CGRect) -> UIImage? {
498 | guard let imagePartRef = srcImg.cgImage?.cropping(to: rect) else {
499 | return nil
500 | }
501 | return UIImage(cgImage: imagePartRef)
502 | }
503 |
504 | // 图像旋转
505 | static func imageRotation(image: UIImage, orientation: UIImage.Orientation) -> UIImage {
506 | var rotate: Double = 0.0
507 | var rect: CGRect
508 | var translateX: CGFloat = 0.0
509 | var translateY: CGFloat = 0.0
510 | var scaleX: CGFloat = 1.0
511 | var scaleY: CGFloat = 1.0
512 |
513 | switch orientation {
514 | case .left:
515 | rotate = .pi / 2
516 | rect = CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width)
517 | translateX = 0
518 | translateY = -rect.size.width
519 | scaleY = rect.size.width / rect.size.height
520 | scaleX = rect.size.height / rect.size.width
521 | case .right:
522 | rotate = 3 * .pi / 2
523 | rect = CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width)
524 | translateX = -rect.size.height
525 | translateY = 0
526 | scaleY = rect.size.width / rect.size.height
527 | scaleX = rect.size.height / rect.size.width
528 | case .down:
529 | rotate = .pi
530 | rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
531 | translateX = -rect.size.width
532 | translateY = -rect.size.height
533 | default:
534 | rotate = 0.0
535 | rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
536 | translateX = 0
537 | translateY = 0
538 | }
539 |
540 | UIGraphicsBeginImageContext(rect.size)
541 | let context = UIGraphicsGetCurrentContext()!
542 | // 做CTM变换
543 | context.translateBy(x: 0.0, y: rect.size.height)
544 | context.scaleBy(x: 1.0, y: -1.0)
545 | context.rotate(by: CGFloat(rotate))
546 | context.translateBy(x: translateX, y: translateY)
547 |
548 | context.scaleBy(x: scaleX, y: scaleY)
549 | // 绘制图片
550 | context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height))
551 | return UIGraphicsGetImageFromCurrentImageContext()!
552 | }
553 |
554 | }
555 |
--------------------------------------------------------------------------------
/SwiftScanner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SwiftScanner/SwiftScanner.h:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftScanner.h
3 | // SwiftScanner
4 | //
5 | // Created by 杨西川 on 16/09/2017.
6 | // Copyright © 2017 xialibing. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for SwiftScanner.
12 | FOUNDATION_EXPORT double SwiftScannerVersionNumber;
13 |
14 | //! Project version string for SwiftScanner.
15 | FOUNDATION_EXPORT const unsigned char SwiftScannerVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/swiftScan.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'swiftScan'
3 | s.version = '1.2.1'
4 | s.summary = 'ios swift scan wrapper'
5 | s.homepage = 'https://github.com/MxABC/swiftScan'
6 | s.license = 'MIT'
7 | s.authors = {'MxABC' => 'lbxia20091227@foxmail.com'}
8 | s.platform = :ios, '8.0'
9 | s.source = {:git => 'https://github.com/MxABC/swiftScan.git', :tag => s.version}
10 | s.ios.deployment_target = "8.0"
11 | s.source_files = 'Source/*.swift'
12 | end
13 |
--------------------------------------------------------------------------------
/swiftScan.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 488928AE1C1A6F4D005A8F83 /* swiftScan.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 488928AD1C1A6F4D005A8F83 /* swiftScan.podspec */; };
11 | 488928E31C1A7BE4005A8F83 /* LBXScanLineAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928DD1C1A7BE4005A8F83 /* LBXScanLineAnimation.swift */; };
12 | 488928E41C1A7BE4005A8F83 /* LBXScanNetAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928DE1C1A7BE4005A8F83 /* LBXScanNetAnimation.swift */; };
13 | 488928E51C1A7BE4005A8F83 /* LBXScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928DF1C1A7BE4005A8F83 /* LBXScanView.swift */; };
14 | 488928E61C1A7BE4005A8F83 /* LBXScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928E01C1A7BE4005A8F83 /* LBXScanViewController.swift */; };
15 | 488928E71C1A7BE4005A8F83 /* LBXScanViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928E11C1A7BE4005A8F83 /* LBXScanViewStyle.swift */; };
16 | 488928E81C1A7BE4005A8F83 /* LBXScanWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488928E21C1A7BE4005A8F83 /* LBXScanWrapper.swift */; };
17 | 48B143C41C17C98B00B2E7D5 /* MainTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B143C31C17C98B00B2E7D5 /* MainTableViewController.swift */; };
18 | 48B143CA1C1809E700B2E7D5 /* CodeScan.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 48B143C91C1809E700B2E7D5 /* CodeScan.bundle */; };
19 | 48D3BBD11C70104100823F87 /* LBXPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D3BBD01C70104100823F87 /* LBXPermissions.swift */; };
20 | 73FF0B8E1CF545FE0083F169 /* ScanResultController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 73FF0B8A1CF545FE0083F169 /* ScanResultController.xib */; };
21 | 73FF0B8F1CF545FE0083F169 /* ScanResultController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FF0B8B1CF545FE0083F169 /* ScanResultController.swift */; };
22 | 73FF0B901CF545FE0083F169 /* MyCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FF0B8C1CF545FE0083F169 /* MyCodeViewController.swift */; };
23 | 73FF0B911CF545FE0083F169 /* QQScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FF0B8D1CF545FE0083F169 /* QQScanViewController.swift */; };
24 | 7D42B9B01C05EE9A0084D045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D42B9AF1C05EE9A0084D045 /* AppDelegate.swift */; };
25 | 7D42B9B21C05EE9A0084D045 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D42B9B11C05EE9A0084D045 /* ViewController.swift */; };
26 | 7D42B9B51C05EE9A0084D045 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7D42B9B31C05EE9A0084D045 /* Main.storyboard */; };
27 | 7D42B9B71C05EE9A0084D045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7D42B9B61C05EE9A0084D045 /* Assets.xcassets */; };
28 | 7D42B9BA1C05EE9A0084D045 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7D42B9B81C05EE9A0084D045 /* LaunchScreen.storyboard */; };
29 | 7DA82E091C19CE5E0028B5DB /* logo.JPG in Resources */ = {isa = PBXBuildFile; fileRef = 7DA82E081C19CE5E0028B5DB /* logo.JPG */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXCopyFilesBuildPhase section */
33 | D6DC97001F6D0C0200E1CCEB /* Embed Frameworks */ = {
34 | isa = PBXCopyFilesBuildPhase;
35 | buildActionMask = 2147483647;
36 | dstPath = "";
37 | dstSubfolderSpec = 10;
38 | files = (
39 | );
40 | name = "Embed Frameworks";
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXCopyFilesBuildPhase section */
44 |
45 | /* Begin PBXFileReference section */
46 | 488928AD1C1A6F4D005A8F83 /* swiftScan.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = swiftScan.podspec; sourceTree = ""; };
47 | 488928DD1C1A7BE4005A8F83 /* LBXScanLineAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanLineAnimation.swift; sourceTree = ""; };
48 | 488928DE1C1A7BE4005A8F83 /* LBXScanNetAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanNetAnimation.swift; sourceTree = ""; };
49 | 488928DF1C1A7BE4005A8F83 /* LBXScanView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanView.swift; sourceTree = ""; };
50 | 488928E01C1A7BE4005A8F83 /* LBXScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanViewController.swift; sourceTree = ""; };
51 | 488928E11C1A7BE4005A8F83 /* LBXScanViewStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanViewStyle.swift; sourceTree = ""; };
52 | 488928E21C1A7BE4005A8F83 /* LBXScanWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXScanWrapper.swift; sourceTree = ""; };
53 | 48B143C31C17C98B00B2E7D5 /* MainTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTableViewController.swift; sourceTree = ""; };
54 | 48B143C91C1809E700B2E7D5 /* CodeScan.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = CodeScan.bundle; sourceTree = ""; };
55 | 48D3BBD01C70104100823F87 /* LBXPermissions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LBXPermissions.swift; sourceTree = ""; };
56 | 73FF0B8A1CF545FE0083F169 /* ScanResultController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ScanResultController.xib; sourceTree = ""; };
57 | 73FF0B8B1CF545FE0083F169 /* ScanResultController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanResultController.swift; sourceTree = ""; };
58 | 73FF0B8C1CF545FE0083F169 /* MyCodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyCodeViewController.swift; sourceTree = ""; };
59 | 73FF0B8D1CF545FE0083F169 /* QQScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QQScanViewController.swift; sourceTree = ""; };
60 | 7D42B9AC1C05EE9A0084D045 /* swiftScan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftScan.app; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 7D42B9AF1C05EE9A0084D045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
62 | 7D42B9B11C05EE9A0084D045 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
63 | 7D42B9B41C05EE9A0084D045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
64 | 7D42B9B61C05EE9A0084D045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
65 | 7D42B9B91C05EE9A0084D045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
66 | 7D42B9BB1C05EE9A0084D045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
67 | 7D46320C1C18683A00D70CF1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; };
68 | 7D46320D1C18683A00D70CF1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; };
69 | 7DA82E081C19CE5E0028B5DB /* logo.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = logo.JPG; sourceTree = ""; };
70 | D6DC96F61F6D0C0200E1CCEB /* SwiftScanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftScanner.h; sourceTree = ""; };
71 | D6DC96F71F6D0C0200E1CCEB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
72 | /* End PBXFileReference section */
73 |
74 | /* Begin PBXFrameworksBuildPhase section */
75 | 7D42B9A91C05EE9A0084D045 /* Frameworks */ = {
76 | isa = PBXFrameworksBuildPhase;
77 | buildActionMask = 2147483647;
78 | files = (
79 | );
80 | runOnlyForDeploymentPostprocessing = 0;
81 | };
82 | /* End PBXFrameworksBuildPhase section */
83 |
84 | /* Begin PBXGroup section */
85 | 488928DC1C1A7BE4005A8F83 /* Source */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 48D3BBD01C70104100823F87 /* LBXPermissions.swift */,
89 | 488928DD1C1A7BE4005A8F83 /* LBXScanLineAnimation.swift */,
90 | 488928DE1C1A7BE4005A8F83 /* LBXScanNetAnimation.swift */,
91 | 488928DF1C1A7BE4005A8F83 /* LBXScanView.swift */,
92 | 488928E01C1A7BE4005A8F83 /* LBXScanViewController.swift */,
93 | 488928E11C1A7BE4005A8F83 /* LBXScanViewStyle.swift */,
94 | 488928E21C1A7BE4005A8F83 /* LBXScanWrapper.swift */,
95 | );
96 | path = Source;
97 | sourceTree = "";
98 | };
99 | 7D42B9A31C05EE9A0084D045 = {
100 | isa = PBXGroup;
101 | children = (
102 | 488928AD1C1A6F4D005A8F83 /* swiftScan.podspec */,
103 | 488928DC1C1A7BE4005A8F83 /* Source */,
104 | 7D42B9AE1C05EE9A0084D045 /* swiftScan */,
105 | D6DC96F51F6D0C0200E1CCEB /* SwiftScanner */,
106 | 7D42B9AD1C05EE9A0084D045 /* Products */,
107 | );
108 | sourceTree = "";
109 | };
110 | 7D42B9AD1C05EE9A0084D045 /* Products */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 7D42B9AC1C05EE9A0084D045 /* swiftScan.app */,
114 | );
115 | name = Products;
116 | sourceTree = "";
117 | };
118 | 7D42B9AE1C05EE9A0084D045 /* swiftScan */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 73FF0B8A1CF545FE0083F169 /* ScanResultController.xib */,
122 | 73FF0B8B1CF545FE0083F169 /* ScanResultController.swift */,
123 | 73FF0B8C1CF545FE0083F169 /* MyCodeViewController.swift */,
124 | 73FF0B8D1CF545FE0083F169 /* QQScanViewController.swift */,
125 | 7DA82E081C19CE5E0028B5DB /* logo.JPG */,
126 | 48B143C91C1809E700B2E7D5 /* CodeScan.bundle */,
127 | 7D42B9AF1C05EE9A0084D045 /* AppDelegate.swift */,
128 | 7D42B9B11C05EE9A0084D045 /* ViewController.swift */,
129 | 7D42B9B31C05EE9A0084D045 /* Main.storyboard */,
130 | 7D42B9B61C05EE9A0084D045 /* Assets.xcassets */,
131 | 7D42B9B81C05EE9A0084D045 /* LaunchScreen.storyboard */,
132 | 7D42B9BB1C05EE9A0084D045 /* Info.plist */,
133 | 48B143C31C17C98B00B2E7D5 /* MainTableViewController.swift */,
134 | );
135 | path = swiftScan;
136 | sourceTree = "";
137 | };
138 | D6DC96F51F6D0C0200E1CCEB /* SwiftScanner */ = {
139 | isa = PBXGroup;
140 | children = (
141 | D6DC96F61F6D0C0200E1CCEB /* SwiftScanner.h */,
142 | D6DC96F71F6D0C0200E1CCEB /* Info.plist */,
143 | );
144 | path = SwiftScanner;
145 | sourceTree = "";
146 | };
147 | /* End PBXGroup section */
148 |
149 | /* Begin PBXNativeTarget section */
150 | 7D42B9AB1C05EE9A0084D045 /* swiftScan */ = {
151 | isa = PBXNativeTarget;
152 | buildConfigurationList = 7D42B9BE1C05EE9A0084D045 /* Build configuration list for PBXNativeTarget "swiftScan" */;
153 | buildPhases = (
154 | 7D42B9A81C05EE9A0084D045 /* Sources */,
155 | 7D42B9A91C05EE9A0084D045 /* Frameworks */,
156 | 7D42B9AA1C05EE9A0084D045 /* Resources */,
157 | D6DC97001F6D0C0200E1CCEB /* Embed Frameworks */,
158 | );
159 | buildRules = (
160 | );
161 | dependencies = (
162 | );
163 | name = swiftScan;
164 | productName = swiftScan;
165 | productReference = 7D42B9AC1C05EE9A0084D045 /* swiftScan.app */;
166 | productType = "com.apple.product-type.application";
167 | };
168 | /* End PBXNativeTarget section */
169 |
170 | /* Begin PBXProject section */
171 | 7D42B9A41C05EE9A0084D045 /* Project object */ = {
172 | isa = PBXProject;
173 | attributes = {
174 | LastSwiftUpdateCheck = 0710;
175 | LastUpgradeCheck = 1000;
176 | ORGANIZATIONNAME = xialibing;
177 | TargetAttributes = {
178 | 7D42B9AB1C05EE9A0084D045 = {
179 | CreatedOnToolsVersion = 7.1;
180 | DevelopmentTeam = 8LQ7CL73D8;
181 | LastSwiftMigration = 0820;
182 | ProvisioningStyle = Automatic;
183 | };
184 | };
185 | };
186 | buildConfigurationList = 7D42B9A71C05EE9A0084D045 /* Build configuration list for PBXProject "swiftScan" */;
187 | compatibilityVersion = "Xcode 3.2";
188 | developmentRegion = en;
189 | hasScannedForEncodings = 0;
190 | knownRegions = (
191 | en,
192 | Base,
193 | "zh-Hans",
194 | );
195 | mainGroup = 7D42B9A31C05EE9A0084D045;
196 | productRefGroup = 7D42B9AD1C05EE9A0084D045 /* Products */;
197 | projectDirPath = "";
198 | projectRoot = "";
199 | targets = (
200 | 7D42B9AB1C05EE9A0084D045 /* swiftScan */,
201 | );
202 | };
203 | /* End PBXProject section */
204 |
205 | /* Begin PBXResourcesBuildPhase section */
206 | 7D42B9AA1C05EE9A0084D045 /* Resources */ = {
207 | isa = PBXResourcesBuildPhase;
208 | buildActionMask = 2147483647;
209 | files = (
210 | 48B143CA1C1809E700B2E7D5 /* CodeScan.bundle in Resources */,
211 | 7D42B9BA1C05EE9A0084D045 /* LaunchScreen.storyboard in Resources */,
212 | 7D42B9B71C05EE9A0084D045 /* Assets.xcassets in Resources */,
213 | 73FF0B8E1CF545FE0083F169 /* ScanResultController.xib in Resources */,
214 | 7DA82E091C19CE5E0028B5DB /* logo.JPG in Resources */,
215 | 7D42B9B51C05EE9A0084D045 /* Main.storyboard in Resources */,
216 | 488928AE1C1A6F4D005A8F83 /* swiftScan.podspec in Resources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXResourcesBuildPhase section */
221 |
222 | /* Begin PBXSourcesBuildPhase section */
223 | 7D42B9A81C05EE9A0084D045 /* Sources */ = {
224 | isa = PBXSourcesBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | 488928E61C1A7BE4005A8F83 /* LBXScanViewController.swift in Sources */,
228 | 73FF0B911CF545FE0083F169 /* QQScanViewController.swift in Sources */,
229 | 48B143C41C17C98B00B2E7D5 /* MainTableViewController.swift in Sources */,
230 | 7D42B9B21C05EE9A0084D045 /* ViewController.swift in Sources */,
231 | 488928E51C1A7BE4005A8F83 /* LBXScanView.swift in Sources */,
232 | 488928E81C1A7BE4005A8F83 /* LBXScanWrapper.swift in Sources */,
233 | 7D42B9B01C05EE9A0084D045 /* AppDelegate.swift in Sources */,
234 | 73FF0B901CF545FE0083F169 /* MyCodeViewController.swift in Sources */,
235 | 488928E71C1A7BE4005A8F83 /* LBXScanViewStyle.swift in Sources */,
236 | 488928E41C1A7BE4005A8F83 /* LBXScanNetAnimation.swift in Sources */,
237 | 73FF0B8F1CF545FE0083F169 /* ScanResultController.swift in Sources */,
238 | 488928E31C1A7BE4005A8F83 /* LBXScanLineAnimation.swift in Sources */,
239 | 48D3BBD11C70104100823F87 /* LBXPermissions.swift in Sources */,
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | /* End PBXSourcesBuildPhase section */
244 |
245 | /* Begin PBXVariantGroup section */
246 | 7D42B9B31C05EE9A0084D045 /* Main.storyboard */ = {
247 | isa = PBXVariantGroup;
248 | children = (
249 | 7D42B9B41C05EE9A0084D045 /* Base */,
250 | 7D46320C1C18683A00D70CF1 /* zh-Hans */,
251 | );
252 | name = Main.storyboard;
253 | sourceTree = "";
254 | };
255 | 7D42B9B81C05EE9A0084D045 /* LaunchScreen.storyboard */ = {
256 | isa = PBXVariantGroup;
257 | children = (
258 | 7D42B9B91C05EE9A0084D045 /* Base */,
259 | 7D46320D1C18683A00D70CF1 /* zh-Hans */,
260 | );
261 | name = LaunchScreen.storyboard;
262 | sourceTree = "";
263 | };
264 | /* End PBXVariantGroup section */
265 |
266 | /* Begin XCBuildConfiguration section */
267 | 7D42B9BC1C05EE9A0084D045 /* Debug */ = {
268 | isa = XCBuildConfiguration;
269 | buildSettings = {
270 | ALWAYS_SEARCH_USER_PATHS = NO;
271 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
272 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
273 | CLANG_CXX_LIBRARY = "libc++";
274 | CLANG_ENABLE_MODULES = YES;
275 | CLANG_ENABLE_OBJC_ARC = YES;
276 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
277 | CLANG_WARN_BOOL_CONVERSION = YES;
278 | CLANG_WARN_COMMA = YES;
279 | CLANG_WARN_CONSTANT_CONVERSION = YES;
280 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
282 | CLANG_WARN_EMPTY_BODY = YES;
283 | CLANG_WARN_ENUM_CONVERSION = YES;
284 | CLANG_WARN_INFINITE_RECURSION = YES;
285 | CLANG_WARN_INT_CONVERSION = YES;
286 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
287 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
288 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
289 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
290 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
291 | CLANG_WARN_STRICT_PROTOTYPES = YES;
292 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
293 | CLANG_WARN_UNREACHABLE_CODE = YES;
294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
295 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
296 | COPY_PHASE_STRIP = NO;
297 | DEBUG_INFORMATION_FORMAT = dwarf;
298 | ENABLE_STRICT_OBJC_MSGSEND = YES;
299 | ENABLE_TESTABILITY = YES;
300 | GCC_C_LANGUAGE_STANDARD = gnu99;
301 | GCC_DYNAMIC_NO_PIC = NO;
302 | GCC_NO_COMMON_BLOCKS = YES;
303 | GCC_OPTIMIZATION_LEVEL = 0;
304 | GCC_PREPROCESSOR_DEFINITIONS = (
305 | "DEBUG=1",
306 | "$(inherited)",
307 | );
308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
310 | GCC_WARN_UNDECLARED_SELECTOR = YES;
311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
312 | GCC_WARN_UNUSED_FUNCTION = YES;
313 | GCC_WARN_UNUSED_VARIABLE = YES;
314 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
315 | MTL_ENABLE_DEBUG_INFO = YES;
316 | ONLY_ACTIVE_ARCH = YES;
317 | SDKROOT = iphoneos;
318 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
319 | SWIFT_VERSION = 3.0;
320 | };
321 | name = Debug;
322 | };
323 | 7D42B9BD1C05EE9A0084D045 /* Release */ = {
324 | isa = XCBuildConfiguration;
325 | buildSettings = {
326 | ALWAYS_SEARCH_USER_PATHS = NO;
327 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
329 | CLANG_CXX_LIBRARY = "libc++";
330 | CLANG_ENABLE_MODULES = YES;
331 | CLANG_ENABLE_OBJC_ARC = YES;
332 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
333 | CLANG_WARN_BOOL_CONVERSION = YES;
334 | CLANG_WARN_COMMA = YES;
335 | CLANG_WARN_CONSTANT_CONVERSION = YES;
336 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
338 | CLANG_WARN_EMPTY_BODY = YES;
339 | CLANG_WARN_ENUM_CONVERSION = YES;
340 | CLANG_WARN_INFINITE_RECURSION = YES;
341 | CLANG_WARN_INT_CONVERSION = YES;
342 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
343 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
344 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
345 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
346 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
347 | CLANG_WARN_STRICT_PROTOTYPES = YES;
348 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
349 | CLANG_WARN_UNREACHABLE_CODE = YES;
350 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
351 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
352 | COPY_PHASE_STRIP = NO;
353 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
354 | ENABLE_NS_ASSERTIONS = NO;
355 | ENABLE_STRICT_OBJC_MSGSEND = YES;
356 | GCC_C_LANGUAGE_STANDARD = gnu99;
357 | GCC_NO_COMMON_BLOCKS = YES;
358 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
359 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
360 | GCC_WARN_UNDECLARED_SELECTOR = YES;
361 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
362 | GCC_WARN_UNUSED_FUNCTION = YES;
363 | GCC_WARN_UNUSED_VARIABLE = YES;
364 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
365 | MTL_ENABLE_DEBUG_INFO = NO;
366 | SDKROOT = iphoneos;
367 | SWIFT_COMPILATION_MODE = wholemodule;
368 | SWIFT_VERSION = 3.0;
369 | VALIDATE_PRODUCT = YES;
370 | };
371 | name = Release;
372 | };
373 | 7D42B9BF1C05EE9A0084D045 /* Debug */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
377 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
378 | CODE_SIGN_IDENTITY = "iPhone Developer";
379 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
380 | CODE_SIGN_STYLE = Automatic;
381 | DEVELOPMENT_TEAM = 8LQ7CL73D8;
382 | INFOPLIST_FILE = swiftScan/Info.plist;
383 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
385 | PRODUCT_BUNDLE_IDENTIFIER = com.lbx.hk2019235;
386 | PRODUCT_NAME = "$(TARGET_NAME)";
387 | PROVISIONING_PROFILE = "5afb03a3-32bd-412b-9db2-5fa2d3271415";
388 | PROVISIONING_PROFILE_SPECIFIER = "";
389 | SWIFT_VERSION = 5.0;
390 | };
391 | name = Debug;
392 | };
393 | 7D42B9C01C05EE9A0084D045 /* Release */ = {
394 | isa = XCBuildConfiguration;
395 | buildSettings = {
396 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
397 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
398 | CODE_SIGN_IDENTITY = "iPhone Developer";
399 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
400 | CODE_SIGN_STYLE = Automatic;
401 | DEVELOPMENT_TEAM = LM3HW8FY8K;
402 | INFOPLIST_FILE = swiftScan/Info.plist;
403 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
404 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
405 | PRODUCT_BUNDLE_IDENTIFIER = com.51shaoxi.github.swiftScan;
406 | PRODUCT_NAME = "$(TARGET_NAME)";
407 | PROVISIONING_PROFILE = "5afb03a3-32bd-412b-9db2-5fa2d3271415";
408 | PROVISIONING_PROFILE_SPECIFIER = "";
409 | SWIFT_VERSION = 5.0;
410 | };
411 | name = Release;
412 | };
413 | /* End XCBuildConfiguration section */
414 |
415 | /* Begin XCConfigurationList section */
416 | 7D42B9A71C05EE9A0084D045 /* Build configuration list for PBXProject "swiftScan" */ = {
417 | isa = XCConfigurationList;
418 | buildConfigurations = (
419 | 7D42B9BC1C05EE9A0084D045 /* Debug */,
420 | 7D42B9BD1C05EE9A0084D045 /* Release */,
421 | );
422 | defaultConfigurationIsVisible = 0;
423 | defaultConfigurationName = Release;
424 | };
425 | 7D42B9BE1C05EE9A0084D045 /* Build configuration list for PBXNativeTarget "swiftScan" */ = {
426 | isa = XCConfigurationList;
427 | buildConfigurations = (
428 | 7D42B9BF1C05EE9A0084D045 /* Debug */,
429 | 7D42B9C01C05EE9A0084D045 /* Release */,
430 | );
431 | defaultConfigurationIsVisible = 0;
432 | defaultConfigurationName = Release;
433 | };
434 | /* End XCConfigurationList section */
435 | };
436 | rootObject = 7D42B9A41C05EE9A0084D045 /* Project object */;
437 | }
438 |
--------------------------------------------------------------------------------
/swiftScan.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/swiftScan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/swiftScan.xcodeproj/xcshareddata/xcschemes/SwiftScanner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/swiftScan/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/11/25.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
17 |
18 | // window? = UIWindow()
19 | // window?.frame = UIScreen.main.bounds;
20 | //
21 | // window?.rootViewController = UINavigationController(rootViewController: MainTableViewController())
22 | //
23 | // window?.makeKeyAndVisible();
24 | return true
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/swiftScan/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/swiftScan/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/swiftScan/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/device_scan@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/device_scan@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_Scan_weixin_Line@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_Scan_weixin_Line@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_flash_down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_flash_down@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_flash_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_flash_nor@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_myqrcode_down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_myqrcode_down@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_myqrcode_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_myqrcode_nor@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_photo_down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_photo_down@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_photo_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_photo_nor@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_btn_scan_off@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_btn_scan_off@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_full_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_full_net.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_light_green@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_light_green@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_part_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_part_net.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_titlebar_back_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_titlebar_back_nor@2x.png
--------------------------------------------------------------------------------
/swiftScan/CodeScan.bundle/qrcode_scan_titlebar_back_pressed@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/CodeScan.bundle/qrcode_scan_titlebar_back_pressed@2x.png
--------------------------------------------------------------------------------
/swiftScan/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppleMusicUsageDescription
26 | 请点击“允许”以允许访问
27 | NSBluetoothPeripheralUsageDescription
28 | 请点击“允许”以允许访问
29 | NSCalendarsUsageDescription
30 | 请点击“允许”以允许访问
31 | NSCameraUsageDescription
32 | 请点击“允许”以允许访问
33 | NSHealthShareUsageDescription
34 | 请点击“允许”以允许访问
35 | NSHealthUpdateUsageDescription
36 | 请点击“允许”以允许访问
37 | NSLocationAlwaysUsageDescription
38 | 请点击“允许”以允许访问
39 | NSLocationUsageDescription
40 | 请点击“允许”以允许访问
41 | NSLocationWhenInUseUsageDescription
42 | 请点击“允许”以允许访问
43 | NSMicrophoneUsageDescription
44 | 请点击“允许”以允许访问
45 | NSMotionUsageDescription
46 | 请点击“允许”以允许访问
47 | NSPhotoLibraryAddUsageDescription
48 | 请允许访问您的相册
49 | NSPhotoLibraryUsageDescription
50 | 请点击“允许”以允许访问
51 | NSRemindersUsageDescription
52 | 请点击“允许”以允许访问
53 | UILaunchStoryboardName
54 | LaunchScreen
55 | UIMainStoryboardFile
56 | Main
57 | UIRequiredDeviceCapabilities
58 |
59 | armv7
60 |
61 | UISupportedInterfaceOrientations
62 |
63 | UIInterfaceOrientationPortrait
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/swiftScan/MainTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainTableViewController.swift
3 | // swiftScan
4 | //
5 | // Created by lbxia on 15/12/9.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Foundation
11 | import AVFoundation
12 |
13 | class MainTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
14 |
15 | var arrayItems: Array> = [
16 | ["模拟qq扫码界面", "qqStyle"],
17 | ["模仿支付宝扫码区域", "ZhiFuBaoStyle"],
18 | ["模仿微信扫码区域", "weixinStyle"],
19 | ["无边框,内嵌4个角", "InnerStyle"],
20 | ["4个角在矩形框线上,网格动画", "OnStyle"],
21 | ["自定义颜色", "changeColor"],
22 | ["只识别框内", "recoCropRect"],
23 | ["改变尺寸", "changeSize"],
24 | ["条形码效果", "notSquare"],
25 | ["二维码/条形码生成", "myCode"],
26 | ["相册", "openLocalPhotoAlbum"]
27 | ]
28 |
29 | override func viewDidLoad() {
30 | super.viewDidLoad()
31 |
32 | self.title = "swift 扫一扫"
33 |
34 | self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")
35 | self.tableView.delegate = self
36 | self.tableView.dataSource = self
37 | }
38 |
39 | // MARK: - Table view data source
40 |
41 | func numberOfSectionsInTableView(tableView: UITableView) -> Int {
42 | // #warning Incomplete implementation, return the number of sections
43 | return 1
44 | }
45 |
46 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
47 | // #warning Incomplete implementation, return the number of rows
48 | return arrayItems.count
49 | }
50 |
51 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
52 | let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath as IndexPath)
53 |
54 | // Configure the cell...
55 | cell.textLabel?.text = arrayItems[indexPath.row].first
56 |
57 | return cell
58 | }
59 | func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
60 |
61 | //objc_msgSend对应方法好像没有
62 | let sel = NSSelectorFromString(arrayItems[indexPath.row].last!)
63 |
64 | self.InnerStyle()
65 |
66 | tableView.deselectRow(at: indexPath as IndexPath, animated: true)
67 |
68 | }
69 |
70 | // MARK: - ---模仿qq扫码界面---------
71 | func qqStyle() {
72 | print("qqStyle")
73 |
74 | let vc = QQScanViewController()
75 | var style = LBXScanViewStyle()
76 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
77 | vc.scanStyle = style
78 | self.navigationController?.pushViewController(vc, animated: true)
79 |
80 | }
81 |
82 | // MARK: - --模仿支付宝------
83 | func ZhiFuBaoStyle() {
84 | //设置扫码区域参数
85 | var style = LBXScanViewStyle()
86 |
87 | style.centerUpOffset = 60
88 | style.xScanRetangleOffset = 30
89 |
90 | if UIScreen.main.bounds.size.height <= 480 {
91 | //3.5inch 显示的扫码缩小
92 | style.centerUpOffset = 40
93 | style.xScanRetangleOffset = 20
94 | }
95 |
96 | style.color_NotRecoginitonArea = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 0.4)
97 |
98 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
99 | style.photoframeLineW = 2.0
100 | style.photoframeAngleW = 16
101 | style.photoframeAngleH = 16
102 |
103 | style.isNeedShowRetangle = false
104 |
105 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
106 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_full_net")
107 |
108 | let vc = LBXScanViewController()
109 |
110 | vc.scanStyle = style
111 | self.navigationController?.pushViewController(vc, animated: true)
112 |
113 | }
114 |
115 | func createImageWithColor(color: UIColor) -> UIImage {
116 | let rect=CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
117 | UIGraphicsBeginImageContext(rect.size)
118 | let context = UIGraphicsGetCurrentContext()
119 | context!.setFillColor(color.cgColor)
120 | context!.fill(rect)
121 | let theImage = UIGraphicsGetImageFromCurrentImageContext()
122 | UIGraphicsEndImageContext()
123 | return theImage!
124 | }
125 |
126 | // MARK: - ------条形码扫码界面 ---------
127 | func notSquare() {
128 | //设置扫码区域参数
129 | //设置扫码区域参数
130 | var style = LBXScanViewStyle()
131 |
132 | style.centerUpOffset = 44
133 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
134 | style.photoframeLineW = 4
135 | style.photoframeAngleW = 28
136 | style.photoframeAngleH = 16
137 | style.isNeedShowRetangle = false
138 |
139 | style.anmiationStyle = LBXScanViewAnimationStyle.LineStill
140 |
141 | style.animationImage = createImageWithColor(color: UIColor.red)
142 | //非正方形
143 | //设置矩形宽高比
144 | style.whRatio = 4.3/2.18
145 |
146 | //离左边和右边距离
147 | style.xScanRetangleOffset = 30
148 |
149 | let vc = LBXScanViewController()
150 |
151 | vc.scanStyle = style
152 | self.navigationController?.pushViewController(vc, animated: true)
153 |
154 | }
155 |
156 | // MARK: - ---无边框,内嵌4个角 -----
157 | func InnerStyle() {
158 | //设置扫码区域参数
159 | var style = LBXScanViewStyle()
160 | style.centerUpOffset = 44
161 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
162 | style.photoframeLineW = 3
163 | style.photoframeAngleW = 18
164 | style.photoframeAngleH = 18
165 | style.isNeedShowRetangle = false
166 |
167 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
168 |
169 | //qq里面的线条图片
170 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
171 |
172 | let vc = LBXScanViewController()
173 | vc.scanStyle = style
174 | self.navigationController?.pushViewController(vc, animated: true)
175 |
176 | }
177 |
178 | // MARK: - --无边框,内嵌4个角------
179 | func weixinStyle() {
180 | //设置扫码区域参数
181 | var style = LBXScanViewStyle()
182 | style.centerUpOffset = 44
183 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
184 | style.photoframeLineW = 2
185 | style.photoframeAngleW = 18
186 | style.photoframeAngleH = 18
187 | style.isNeedShowRetangle = false
188 |
189 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
190 |
191 | style.colorAngle = UIColor(red: 0.0/255, green: 200.0/255.0, blue: 20.0/255.0, alpha: 1.0)
192 |
193 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_Scan_weixin_Line")
194 |
195 | let vc = LBXScanViewController()
196 | vc.scanStyle = style
197 | self.navigationController?.pushViewController(vc, animated: true)
198 | }
199 |
200 | // MARK: - ---框内区域识别
201 | func recoCropRect() {
202 | //设置扫码区域参数
203 | var style = LBXScanViewStyle()
204 | style.centerUpOffset = 44
205 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
206 | style.photoframeLineW = 6
207 | style.photoframeAngleW = 24
208 | style.photoframeAngleH = 24
209 | style.isNeedShowRetangle = true
210 |
211 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
212 |
213 | //矩形框离左边缘及右边缘的距离
214 | style.xScanRetangleOffset = 80
215 |
216 | //使用的支付宝里面网格图片
217 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_part_net")
218 |
219 | let vc = LBXScanViewController()
220 | vc.scanStyle = style
221 |
222 | vc.isOpenInterestRect = true
223 | //TODO:待设置框内识别
224 | self.navigationController?.pushViewController(vc, animated: true)
225 |
226 | }
227 |
228 | // MARK: - ----4个角在矩形框线上,网格动画
229 | func OnStyle() {
230 | //设置扫码区域参数
231 | var style = LBXScanViewStyle()
232 | style.centerUpOffset = 44
233 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
234 | style.photoframeLineW = 6
235 | style.photoframeAngleW = 24
236 | style.photoframeAngleH = 24
237 | style.isNeedShowRetangle = true
238 |
239 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
240 |
241 | //使用的支付宝里面网格图片
242 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_part_net")
243 |
244 | let vc = LBXScanViewController()
245 | vc.scanStyle = style
246 | self.navigationController?.pushViewController(vc, animated: true)
247 |
248 | }
249 |
250 | // MARK: - ------自定义4个角及矩形框颜色
251 | func changeColor() {
252 | //设置扫码区域参数
253 | var style = LBXScanViewStyle()
254 | style.centerUpOffset = 44
255 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
256 | style.photoframeLineW = 6
257 | style.photoframeAngleW = 24
258 | style.photoframeAngleH = 24
259 | style.isNeedShowRetangle = true
260 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
261 |
262 | //使用的支付宝里面网格图片
263 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
264 |
265 | //4个角的颜色
266 | style.colorAngle = UIColor(red: 65.0/255.0, green: 174.0/255.0, blue: 57.0/255.0, alpha: 1.0)
267 |
268 | //矩形框颜色
269 | style.colorRetangleLine = UIColor(red: 247.0/255.0, green: 202.0/255.0, blue: 15.0/255.0, alpha: 1.0)
270 |
271 | //非矩形框区域颜色
272 | style.color_NotRecoginitonArea = UIColor(red: 247.0/255.0, green: 202.0/255.0, blue: 15.0/255.0, alpha: 0.2)
273 |
274 | let vc = LBXScanViewController()
275 | vc.scanStyle = style
276 |
277 | self.navigationController?.pushViewController(vc, animated: true)
278 |
279 | }
280 |
281 | // MARK: - -----改变扫码区域位置
282 | func changeSize() {
283 | //设置扫码区域参数
284 | var style = LBXScanViewStyle()
285 |
286 | //矩形框向上移动
287 | style.centerUpOffset = 60
288 | //矩形框离左边缘及右边缘的距离
289 | style.xScanRetangleOffset = 100
290 |
291 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
292 | style.photoframeLineW = 6
293 | style.photoframeAngleW = 24
294 | style.photoframeAngleH = 24
295 | style.isNeedShowRetangle = true
296 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
297 |
298 | //qq里面的线条图片
299 |
300 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
301 | let vc = LBXScanViewController()
302 | vc.scanStyle = style
303 |
304 | self.navigationController?.pushViewController(vc, animated: true)
305 |
306 | }
307 |
308 | // MARK: - ------- 相册
309 | func openLocalPhotoAlbum() {
310 | let picker = UIImagePickerController()
311 |
312 |
313 | picker.sourceType = UIImagePickerController.SourceType.photoLibrary
314 |
315 | picker.delegate = self;
316 |
317 |
318 | picker.allowsEditing = true
319 |
320 | present(picker, animated: true, completion: nil)
321 | }
322 |
323 | // MARK: - ----相册选择图片识别二维码 (条形码没有找到系统方法)
324 | func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: AnyObject]) {
325 | picker.dismiss(animated: true, completion: nil)
326 |
327 | var image:UIImage? = info[UIImagePickerController.InfoKey.editedImage.rawValue] as? UIImage
328 |
329 | if (image == nil )
330 | {
331 | image = info[UIImagePickerController.InfoKey.originalImage.rawValue] as? UIImage
332 | }
333 |
334 | if(image == nil) {
335 | return
336 | }
337 |
338 | if(image != nil) {
339 | let arrayResult = LBXScanWrapper.recognizeQRImage(image: image!)
340 | if arrayResult.count > 0 {
341 | let result = arrayResult[0]
342 |
343 | showMsg(title: result.strBarCodeType, message: result.strScanned)
344 |
345 | return
346 | }
347 | }
348 | showMsg(title: "", message: "识别失败")
349 | }
350 |
351 |
352 | func showMsg(title:String?,message:String?)
353 | {
354 | let alertController = UIAlertController(title: title, message:message, preferredStyle: UIAlertController.Style.alert)
355 |
356 | let alertAction = UIAlertAction(title: "知道了", style: UIAlertAction.Style.default) { (alertAction) -> Void in
357 |
358 | }
359 |
360 | alertController.addAction(alertAction)
361 |
362 | present(alertController, animated: true, completion: nil)
363 | }
364 |
365 | func myCode() {
366 | let vc = MyCodeViewController()
367 | self.navigationController?.pushViewController(vc, animated: true)
368 | }
369 |
370 | }
371 |
--------------------------------------------------------------------------------
/swiftScan/MyCodeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyCodeViewController.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/10.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MyCodeViewController: UIViewController {
12 |
13 | //二维码
14 | var qrView = UIView()
15 | var qrImgView = UIImageView()
16 |
17 | //条形码
18 | var tView = UIView()
19 | var tImgView = UIImageView()
20 |
21 | override func viewDidLoad() {
22 | super.viewDidLoad()
23 |
24 | // Do any additional setup after loading the view.
25 | view.backgroundColor = UIColor.white
26 |
27 | drawCodeShowView()
28 |
29 | createQR1()
30 |
31 | createCode128()
32 | }
33 |
34 | // MARK: - -----二维码、条形码显示位置
35 | func drawCodeShowView() {
36 | //二维码
37 |
38 | let rect = CGRect(x: (self.view.frame.width-self.view.frame.width*5/6)/2, y: 100, width: self.view.frame.width*5/6, height: self.view.frame.width*5/6)
39 | qrView.frame = rect
40 | self.view.addSubview(qrView)
41 |
42 | qrView.backgroundColor = UIColor.white
43 | qrView.layer.shadowOffset = CGSize(width: 0, height: 2)
44 | qrView.layer.shadowRadius = 2
45 | qrView.layer.shadowColor = UIColor.black.cgColor
46 | qrView.layer.shadowOpacity = 0.5
47 |
48 | qrImgView.bounds = CGRect(x: 0, y: 0, width: qrView.frame.width-12, height: qrView.frame.width-12)
49 | qrImgView.center = CGPoint(x: qrView.frame.width/2, y: qrView.frame.height/2)
50 | qrView .addSubview(qrImgView)
51 |
52 | //条形码
53 | tView.frame = CGRect(x: (self.view.frame.width-self.view.frame.width*5/6)/2,
54 | y: rect.maxY+20,
55 | width: self.view.frame.width*5/6,
56 | height: self.view.frame.width*5/6*0.5)
57 | self.view .addSubview(tView)
58 | tView.layer.shadowOffset = CGSize(width: 0, height: 2)
59 | tView.layer.shadowRadius = 2
60 | tView.layer.shadowColor = UIColor.black.cgColor
61 | tView.layer.shadowOpacity = 0.5
62 |
63 | tImgView.bounds = CGRect(x: 0, y: 0, width: tView.frame.width-12, height: tView.frame.height-12)
64 | tImgView.center = CGPoint(x: tView.frame.width/2, y: tView.frame.height/2)
65 | tView .addSubview(tImgView)
66 |
67 | }
68 |
69 | func createQR1() {
70 | // qrView.hidden = false
71 | // tView.hidden = true
72 |
73 | let qrImg = LBXScanWrapper.createCode(codeType: "CIQRCodeGenerator", codeString: "lbxia20091227@foxmail.com", size: qrImgView.bounds.size, qrColor: UIColor.black, bkColor: UIColor.white)
74 |
75 | let logoImg = UIImage(named: "logo.JPG")
76 | qrImgView.image = LBXScanWrapper.addImageLogo(srcImg: qrImg!, logoImg: logoImg!, logoSize: CGSize(width: 30, height: 30))
77 | }
78 |
79 | func createCode128() {
80 |
81 | let qrImg = LBXScanWrapper.createCode128(codeString: "005103906002", size: qrImgView.bounds.size, qrColor: UIColor.black, bkColor: UIColor.white)
82 |
83 | tImgView.image = qrImg
84 |
85 | }
86 |
87 | deinit {
88 | print("MyCodeViewController deinit")
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/swiftScan/QQScanViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QQScanViewController.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/10.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class QQScanViewController: LBXScanViewController {
12 |
13 | /**
14 | @brief 扫码区域上方提示文字
15 | */
16 | var topTitle: UILabel?
17 |
18 | /**
19 | @brief 闪关灯开启状态
20 | */
21 | var isOpenedFlash: Bool = false
22 |
23 | // MARK: - 底部几个功能:开启闪光灯、相册、我的二维码
24 |
25 | //底部显示的功能项
26 | var bottomItemsView: UIView?
27 |
28 | //相册
29 | var btnPhoto: UIButton = UIButton()
30 |
31 | //闪光灯
32 | var btnFlash: UIButton = UIButton()
33 |
34 | //我的二维码
35 | var btnMyQR: UIButton = UIButton()
36 |
37 | override func viewDidLoad() {
38 | super.viewDidLoad()
39 |
40 | //需要识别后的图像
41 | setNeedCodeImage(needCodeImg: true)
42 |
43 | //框向上移动10个像素
44 | scanStyle?.centerUpOffset += 10
45 |
46 | // Do any additional setup after loading the view.
47 | }
48 |
49 | override func viewDidAppear(_ animated: Bool) {
50 |
51 | super.viewDidAppear(animated)
52 |
53 | drawBottomItems()
54 | }
55 |
56 | override func handleCodeResult(arrayResult: [LBXScanResult]) {
57 |
58 | for result: LBXScanResult in arrayResult {
59 | if let str = result.strScanned {
60 | print(str)
61 | }
62 | }
63 |
64 | let result: LBXScanResult = arrayResult[0]
65 |
66 | let vc = ScanResultController()
67 | vc.codeResult = result
68 | navigationController?.pushViewController(vc, animated: true)
69 | }
70 |
71 | func drawBottomItems() {
72 | if (bottomItemsView != nil) {
73 |
74 | return
75 | }
76 |
77 | let yMax = self.view.frame.maxY - self.view.frame.minY
78 |
79 | bottomItemsView = UIView(frame: CGRect(x: 0.0, y: yMax-100, width: self.view.frame.size.width, height: 100 ) )
80 |
81 | bottomItemsView!.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.6)
82 |
83 | self.view .addSubview(bottomItemsView!)
84 |
85 | let size = CGSize(width: 65, height: 87)
86 |
87 | self.btnFlash = UIButton()
88 | btnFlash.bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height)
89 | btnFlash.center = CGPoint(x: bottomItemsView!.frame.width/2, y: bottomItemsView!.frame.height/2)
90 |
91 | btnFlash.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_flash_nor"), for:UIControl.State.normal)
92 | btnFlash.addTarget(self, action: #selector(QQScanViewController.openOrCloseFlash), for: UIControl.Event.touchUpInside)
93 |
94 |
95 | self.btnPhoto = UIButton()
96 | btnPhoto.bounds = btnFlash.bounds
97 | btnPhoto.center = CGPoint(x: bottomItemsView!.frame.width/4, y: bottomItemsView!.frame.height/2)
98 | btnPhoto.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_photo_nor"), for: UIControl.State.normal)
99 | btnPhoto.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_photo_down"), for: UIControl.State.highlighted)
100 | // btnPhoto.addTarget(self, action: Selector(("openPhotoAlbum")), for: UIControlEvents.touchUpInside)
101 |
102 | btnPhoto.addTarget(self, action: #selector(openPhotoAlbum), for: UIControl.Event.touchUpInside)
103 |
104 | self.btnMyQR = UIButton()
105 | btnMyQR.bounds = btnFlash.bounds;
106 | btnMyQR.center = CGPoint(x: bottomItemsView!.frame.width * 3/4, y: bottomItemsView!.frame.height/2);
107 | btnMyQR.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_myqrcode_nor"), for: UIControl.State.normal)
108 | btnMyQR.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_myqrcode_down"), for: UIControl.State.highlighted)
109 | btnMyQR.addTarget(self, action: #selector(myCode), for: UIControl.Event.touchUpInside)
110 |
111 |
112 | bottomItemsView?.addSubview(btnFlash)
113 | bottomItemsView?.addSubview(btnPhoto)
114 | bottomItemsView?.addSubview(btnMyQR)
115 |
116 | view.addSubview(bottomItemsView!)
117 | }
118 |
119 | //开关闪光灯
120 | @objc func openOrCloseFlash() {
121 | scanObj?.changeTorch()
122 |
123 | isOpenedFlash = !isOpenedFlash
124 |
125 | if isOpenedFlash
126 | {
127 | btnFlash.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_flash_down"), for:UIControl.State.normal)
128 | }
129 | else
130 | {
131 | btnFlash.setImage(UIImage(named: "CodeScan.bundle/qrcode_scan_btn_flash_nor"), for:UIControl.State.normal)
132 |
133 | }
134 | }
135 |
136 | @objc func myCode() {
137 | let vc = MyCodeViewController()
138 | self.navigationController?.pushViewController(vc, animated: true)
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/swiftScan/ScanResultController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScanResultController.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/12/11.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ScanResultController: UIViewController {
12 |
13 | @IBOutlet weak var codeImg: UIImageView!
14 | @IBOutlet weak var codeTypeLabel: UILabel!
15 | @IBOutlet weak var codeStringLabel: UILabel!
16 | @IBOutlet weak var concreteCodeImg: UIImageView!
17 |
18 | var codeResult: LBXScanResult?
19 |
20 | override func viewDidLoad() {
21 | super.viewDidLoad()
22 |
23 | self.edgesForExtendedLayout = UIRectEdge(rawValue: 0)
24 |
25 | codeTypeLabel.text = ""
26 | codeStringLabel.text = ""
27 |
28 | // Do any additional setup after loading the view.
29 | }
30 |
31 | override func viewDidAppear(_ animated: Bool) {
32 | super.viewDidAppear(animated)
33 |
34 | codeImg.image = codeResult?.imgScanned
35 | codeTypeLabel.text = "码的类型:" + (codeResult?.strBarCodeType)!
36 | codeStringLabel.text = "码的内容:" + (codeResult?.strScanned)!
37 |
38 | if codeImg.image != nil {
39 |
40 | }
41 | }
42 |
43 | func zoomRect( rect:inout CGRect, srcImg: UIImage) {
44 | rect.origin.x -= 10
45 | rect.origin.y -= 10
46 | rect.size.width += 20
47 | rect.size.height += 20
48 |
49 | if rect.origin.x < 0 {
50 | rect.origin.x = 0
51 | }
52 |
53 | if (rect.origin.y < 0) {
54 | rect.origin.y = 0
55 | }
56 |
57 | if (rect.origin.x + rect.size.width) > srcImg.size.width {
58 | rect.size.width = srcImg.size.width - rect.origin.x - 1
59 | }
60 |
61 | if (rect.origin.y + rect.size.height) > srcImg.size.height {
62 | rect.size.height = srcImg.size.height - rect.origin.y - 1
63 | }
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/swiftScan/ScanResultController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
37 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
63 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/swiftScan/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // swiftScan
4 | //
5 | // Created by xialibing on 15/11/25.
6 | // Copyright © 2015年 xialibing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate, LBXScanViewControllerDelegate {
12 | var tableView: UITableView!
13 |
14 | var arrayItems: Array> = [
15 | ["模拟qq扫码界面", "qqStyle"],
16 | ["模仿支付宝扫码区域", "ZhiFuBaoStyle"],
17 | ["模仿微信扫码区域", "weixinStyle"],
18 | ["无边框,内嵌4个角", "InnerStyle"],
19 | ["4个角在矩形框线上,网格动画", "OnStyle"],
20 | ["自定义颜色", "changeColor"],
21 | ["只识别框内", "recoCropRect"],
22 | ["改变尺寸", "changeSize"],
23 | ["条形码效果", "notSquare"],
24 | ["二维码/条形码生成", "myCode"],
25 | ["相册", "openLocalPhotoAlbum"]
26 | ]
27 |
28 | var isSupportContinuous = false;
29 |
30 | override func viewDidLoad() {
31 | super.viewDidLoad()
32 | tableView = UITableView(frame: CGRect(x: 0, y: 20, width: view.frame.width, height: view.frame.height))
33 | self.title = "swift 扫一扫"
34 | tableView.delegate = self
35 | tableView.dataSource = self
36 | self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")
37 | view.addSubview(tableView)
38 | }
39 |
40 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
41 | // #warning Incomplete implementation, return the number of rows
42 | return arrayItems.count
43 | }
44 |
45 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
46 | let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath as IndexPath)
47 | // Configure the cell...
48 | cell.textLabel?.text = arrayItems[indexPath.row].first
49 |
50 | return cell
51 | }
52 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
53 |
54 | //objc_msgSend对应方法好像没有
55 |
56 | if indexPath.row == 10 {
57 | openLocalPhotoAlbum()
58 | return
59 | }
60 |
61 | isSupportContinuous = false;
62 |
63 | switch indexPath.row {
64 | case 0:
65 | self.qqStyle()
66 | case 1:
67 | self.ZhiFuBaoStyle()
68 | case 2:
69 | self.weixinStyle()
70 | case 3:
71 | self.InnerStyle()
72 | case 4:
73 | self.OnStyle()
74 | case 5:
75 | self.changeColor()
76 | case 6:
77 | self.recoCropRect()
78 | case 7:
79 | self.changeSize()
80 | case 8:
81 | self.notSquare()
82 | case 9:
83 | self.myCode()
84 | case 10:
85 | self.openLocalPhotoAlbum()
86 | default:
87 | break
88 | }
89 |
90 | tableView.deselectRow(at: indexPath as IndexPath, animated: true)
91 |
92 | }
93 |
94 | // MARK: - ---模仿qq扫码界面---------
95 | func qqStyle() {
96 | print("qqStyle")
97 |
98 | let vc = QQScanViewController()
99 | var style = LBXScanViewStyle()
100 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
101 | vc.scanStyle = style
102 | self.navigationController?.pushViewController(vc, animated: true)
103 |
104 | }
105 |
106 | // MARK: - --模仿支付宝------
107 | func ZhiFuBaoStyle() {
108 | //设置扫码区域参数
109 | var style = LBXScanViewStyle()
110 |
111 | style.centerUpOffset = 60
112 | style.xScanRetangleOffset = 30
113 |
114 | if UIScreen.main.bounds.size.height <= 480 {
115 | //3.5inch 显示的扫码缩小
116 | style.centerUpOffset = 40
117 | style.xScanRetangleOffset = 20
118 | }
119 |
120 | style.color_NotRecoginitonArea = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 0.4)
121 |
122 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
123 | style.photoframeLineW = 2.0
124 | style.photoframeAngleW = 16
125 | style.photoframeAngleH = 16
126 |
127 | style.isNeedShowRetangle = false
128 |
129 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
130 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_full_net")
131 |
132 | let vc = LBXScanViewController()
133 |
134 | vc.scanStyle = style
135 | vc.isSupportContinuous = true;
136 |
137 | isSupportContinuous = true;
138 |
139 | vc.scanResultDelegate = self
140 |
141 | self.navigationController?.pushViewController(vc, animated: true)
142 |
143 | }
144 |
145 | func createImageWithColor(color: UIColor) -> UIImage {
146 | let rect=CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
147 | UIGraphicsBeginImageContext(rect.size)
148 | let context = UIGraphicsGetCurrentContext()
149 | context!.setFillColor(color.cgColor)
150 | context!.fill(rect)
151 | let theImage = UIGraphicsGetImageFromCurrentImageContext()
152 | UIGraphicsEndImageContext()
153 | return theImage!
154 | }
155 |
156 | // MARK: - ------条形码扫码界面 ---------
157 | func notSquare() {
158 | //设置扫码区域参数
159 | //设置扫码区域参数
160 | var style = LBXScanViewStyle()
161 |
162 | style.centerUpOffset = 44
163 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
164 | style.photoframeLineW = 4
165 | style.photoframeAngleW = 28
166 | style.photoframeAngleH = 16
167 | style.isNeedShowRetangle = false
168 |
169 | style.anmiationStyle = LBXScanViewAnimationStyle.LineStill
170 |
171 | style.animationImage = createImageWithColor(color: UIColor.red)
172 | //非正方形
173 | //设置矩形宽高比
174 | style.whRatio = 4.3/2.18
175 |
176 | //离左边和右边距离
177 | style.xScanRetangleOffset = 30
178 |
179 | let vc = LBXScanViewController()
180 | vc.scanResultDelegate = self
181 |
182 | vc.scanStyle = style
183 | self.navigationController?.pushViewController(vc, animated: true)
184 |
185 | }
186 |
187 | // MARK: - ---无边框,内嵌4个角 -----
188 | func InnerStyle() {
189 | //设置扫码区域参数
190 | var style = LBXScanViewStyle()
191 | style.centerUpOffset = 44
192 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
193 | style.photoframeLineW = 3
194 | style.photoframeAngleW = 18
195 | style.photoframeAngleH = 18
196 | style.isNeedShowRetangle = false
197 |
198 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
199 |
200 | //qq里面的线条图片
201 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
202 |
203 | let vc = LBXScanViewController()
204 | vc.scanStyle = style
205 | vc.scanResultDelegate = self
206 | self.navigationController?.pushViewController(vc, animated: true)
207 |
208 | }
209 |
210 | // MARK: - --无边框,内嵌4个角------
211 | func weixinStyle() {
212 | //设置扫码区域参数
213 | var style = LBXScanViewStyle()
214 | style.centerUpOffset = 44
215 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.Inner
216 | style.photoframeLineW = 2
217 | style.photoframeAngleW = 18
218 | style.photoframeAngleH = 18
219 | style.isNeedShowRetangle = false
220 |
221 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
222 |
223 | style.colorAngle = UIColor(red: 0.0/255, green: 200.0/255.0, blue: 20.0/255.0, alpha: 1.0)
224 |
225 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_Scan_weixin_Line")
226 |
227 | let vc = LBXScanViewController()
228 | vc.scanStyle = style
229 | vc.scanResultDelegate = self
230 | self.navigationController?.pushViewController(vc, animated: true)
231 | }
232 |
233 | // MARK: - ---框内区域识别
234 | func recoCropRect() {
235 | //设置扫码区域参数
236 | var style = LBXScanViewStyle()
237 | style.centerUpOffset = 44
238 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
239 | style.photoframeLineW = 6
240 | style.photoframeAngleW = 24
241 | style.photoframeAngleH = 24
242 | style.isNeedShowRetangle = true
243 |
244 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
245 |
246 | //矩形框离左边缘及右边缘的距离
247 | style.xScanRetangleOffset = 80
248 |
249 | //使用的支付宝里面网格图片
250 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_part_net")
251 |
252 | let vc = LBXScanViewController()
253 | vc.scanStyle = style
254 |
255 | vc.isOpenInterestRect = true
256 | vc.scanResultDelegate = self
257 |
258 | //TODO:待设置框内识别
259 | self.navigationController?.pushViewController(vc, animated: true)
260 |
261 | }
262 |
263 | // MARK: - ----4个角在矩形框线上,网格动画
264 | func OnStyle() {
265 | //设置扫码区域参数
266 | var style = LBXScanViewStyle()
267 | style.centerUpOffset = 44
268 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
269 | style.photoframeLineW = 6
270 | style.photoframeAngleW = 24
271 | style.photoframeAngleH = 24
272 | style.isNeedShowRetangle = true
273 |
274 | style.anmiationStyle = LBXScanViewAnimationStyle.NetGrid
275 |
276 | //使用的支付宝里面网格图片
277 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_part_net")
278 |
279 | let vc = LBXScanViewController()
280 | vc.scanStyle = style
281 | vc.scanResultDelegate = self
282 |
283 | self.navigationController?.pushViewController(vc, animated: true)
284 |
285 | }
286 |
287 | // MARK: - ------自定义4个角及矩形框颜色
288 | func changeColor() {
289 | //设置扫码区域参数
290 | var style = LBXScanViewStyle()
291 | style.centerUpOffset = 44
292 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
293 | style.photoframeLineW = 6
294 | style.photoframeAngleW = 24
295 | style.photoframeAngleH = 24
296 | style.isNeedShowRetangle = true
297 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
298 |
299 | //使用的支付宝里面网格图片
300 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
301 |
302 | //4个角的颜色
303 | style.colorAngle = UIColor(red: 65.0/255.0, green: 174.0/255.0, blue: 57.0/255.0, alpha: 1.0)
304 |
305 | //矩形框颜色
306 | style.colorRetangleLine = UIColor(red: 247.0/255.0, green: 202.0/255.0, blue: 15.0/255.0, alpha: 1.0)
307 |
308 | //非矩形框区域颜色
309 | style.color_NotRecoginitonArea = UIColor(red: 247.0/255.0, green: 202.0/255.0, blue: 15.0/255.0, alpha: 0.2)
310 |
311 | let vc = LBXScanViewController()
312 | vc.scanStyle = style
313 | vc.readyString = "相机启动中..."
314 | vc.scanResultDelegate = self
315 |
316 | self.navigationController?.pushViewController(vc, animated: true)
317 |
318 | }
319 |
320 | // MARK: - -----改变扫码区域位置
321 | func changeSize() {
322 | //设置扫码区域参数
323 | var style = LBXScanViewStyle()
324 |
325 | //矩形框向上移动
326 | style.centerUpOffset = 60
327 | //矩形框离左边缘及右边缘的距离
328 | style.xScanRetangleOffset = 100
329 |
330 | style.photoframeAngleStyle = LBXScanViewPhotoframeAngleStyle.On
331 | style.photoframeLineW = 6
332 | style.photoframeAngleW = 24
333 | style.photoframeAngleH = 24
334 | style.isNeedShowRetangle = true
335 | style.anmiationStyle = LBXScanViewAnimationStyle.LineMove
336 |
337 | //qq里面的线条图片
338 |
339 | style.animationImage = UIImage(named: "CodeScan.bundle/qrcode_scan_light_green")
340 | let vc = LBXScanViewController()
341 | vc.scanStyle = style
342 | vc.scanResultDelegate = self
343 |
344 | self.navigationController?.pushViewController(vc, animated: true)
345 |
346 | }
347 |
348 | // MARK: - ------- 相册
349 | func openLocalPhotoAlbum() {
350 |
351 | LBXPermissions.authorizePhotoWith { [weak self] (granted) in
352 |
353 | if granted {
354 | if let strongSelf = self {
355 | let picker = UIImagePickerController()
356 |
357 | picker.sourceType = UIImagePickerController.SourceType.photoLibrary
358 | picker.delegate = self;
359 |
360 | picker.allowsEditing = true
361 | strongSelf.present(picker, animated: true, completion: nil)
362 | }
363 | } else {
364 | LBXPermissions.jumpToSystemPrivacySetting()
365 | }
366 | }
367 | }
368 |
369 | // MARK: - ----相册选择图片识别二维码 (条形码没有找到系统方法)
370 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
371 | picker.dismiss(animated: true, completion: nil)
372 |
373 | var image:UIImage? = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
374 |
375 | if (image == nil )
376 | {
377 | image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
378 | }
379 |
380 | if(image == nil) {
381 | return
382 | }
383 |
384 | if(image != nil) {
385 | let arrayResult = LBXScanWrapper.recognizeQRImage(image: image!)
386 | if arrayResult.count > 0 {
387 | let result = arrayResult[0]
388 |
389 | showMsg(title: result.strBarCodeType, message: result.strScanned)
390 |
391 | return
392 | }
393 | }
394 | showMsg(title: "", message: "识别失败")
395 | }
396 |
397 |
398 | func showMsg(title:String?,message:String?)
399 | {
400 | let alertController = UIAlertController(title: title, message:message, preferredStyle: UIAlertController.Style.alert)
401 |
402 | let alertAction = UIAlertAction(title: "知道了", style: UIAlertAction.Style.default) { (alertAction) -> Void in
403 |
404 |
405 | }
406 |
407 | alertController.addAction(alertAction)
408 |
409 | present(alertController, animated: true, completion: nil)
410 | }
411 |
412 | func myCode() {
413 | let vc = MyCodeViewController()
414 | self.navigationController?.pushViewController(vc, animated: true)
415 | }
416 |
417 | func scanFinished(scanResult: LBXScanResult, error: String?) {
418 | NSLog("scanResult:\(scanResult)")
419 |
420 |
421 |
422 | if !isSupportContinuous {
423 |
424 | DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400)) {
425 | let vc = ScanResultController()
426 | vc.codeResult = scanResult
427 | self.navigationController?.pushViewController(vc, animated: true)
428 | }
429 | }
430 |
431 | }
432 |
433 | }
434 |
--------------------------------------------------------------------------------
/swiftScan/logo.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MxABC/swiftScan/b0cc9aea11140125b75d1baaccb16c9567cdf69a/swiftScan/logo.JPG
--------------------------------------------------------------------------------
/swiftScan/zh-Hans.lproj/LaunchScreen.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/swiftScan/zh-Hans.lproj/Main.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------