iOS native implementation of scanning QR code and barcode function limits scanning area
- 2021-12-13 09:51:59
- OfStack
Now Apple iOS system has natively supported the function of 2D code scanning, and it is necessary to import AVFoundation to scan natively.
Scanning preparation
1. Acquisition of camera equipment:
device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
2. Create an input stream
do {
try input = AVCaptureDeviceInput(device: device)
} catch let e as NSError {
print(e.localizedDescription)
}
3. Create an output stream
output = AVCaptureMetadataOutput()
// Sets the agent to refresh in the main thread
output?.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
4. Initialize the connection object
session = AVCaptureSession()
// High quality acquisition rate
session?.canSetSessionPreset(AVCaptureSessionPresetHigh)
session?.addOutput(output)
session?.addInput(input)
5. Set the scan area
// Special attention: Effective scanning area, positioning is to set the right vertex as the origin. The line where the screen width lies is y Axis, the line where the screen height is x Shaft
let x = ((SCREENHeight - QRCodeWidth - topViewHeight) / 2.0) / SCREENHeight
let y = ((SCREENWidth - QRCodeWidth) / 2.0) / SCREENWidth
let width = QRCodeWidth / SCREENHeight
let height = QRCodeWidth / SCREENWidth
output?.rectOfInterest = CGRect(x: x, y: y, width: width, height: height)
6. Set the coding format supported by scan code (set bar code and 2D code compatibility as follows)
output?.metadataObjectTypes = [AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]
Step 7 Start capturing
preview = AVCaptureVideoPreviewLayer(session: session)
preview?.videoGravity = AVLayerVideoGravityResizeAspectFill
preview?.frame = self.view.layer.bounds
self.view.layer.insertSublayer(preview!, at: 0)
session?.startRunning()
Scan animation
The animation here is the scan box animation imitating Alipay
We create a new method to deal with our animation.
fileprivate func scanAnimation() -> CABasicAnimation {
let scanNetAnimation = CABasicAnimation()
// Along Y Axial motion
scanNetAnimation.keyPath = "transform.translation.y"
// The height of the scan box. Note: This is the opposite of the actual height
scanNetAnimation.byValue = QRCodeWidth
// Duration of animation
scanNetAnimation.duration = 1.5
// Number of repetitions of animation
scanNetAnimation.repeatCount = MAXFLOAT
return scanNetAnimation
}
Use animation:
When we created the interface, the scan box had an UIImageView, and we needed to add our animation to this ImageView.
scanImageView?.layer.add(scanAnimation(), forKey: nil)
Processing after scanning
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects.count > 0 {
session?.stopRunning()
let metadataObject = metadataObjects[0] as AnyObject
let stringValue: String = metadataObject.stringValue
let vc = QRCodeResultViewController.instantiate()
vc.resultStr = stringValue
self.navigationController?.pushViewController(vc, animated: true)
}
}
Click on the processing of scan results
do {
try input = AVCaptureDeviceInput(device: device)
} catch let e as NSError {
print(e.localizedDescription)
}
0
We can use
do {
try input = AVCaptureDeviceInput(device: device)
} catch let e as NSError {
print(e.localizedDescription)
}
1
Open the connection in Safari. However, it is best to control the events in its own program. After iOS 9, Apple introduced SFSafariViewController, which can be used to display the web pages to be browsed.
do {
try input = AVCaptureDeviceInput(device: device)
} catch let e as NSError {
print(e.localizedDescription)
}
2