~~~写在前面的话~~~
我之前打算做一个APP,然后把电话号码生成二维码 或者条形码, 用手机扫描,这样,就不用担心会输入错误电话号码了。
在下面是实现的扫描二维码的功能中,扫描完成,将会把扫描到的号码 拨打出去。~~~
关于应用之间的切换,参考链接:
http://blog.sina.com.cn/s/blog_7ea0400d0102uy01.html~~CSDN不知道怎么了,贴代码的地方不能有横向的滚动条了,不过,可以用下面的方法查看到具体代码呢~~
------------我是分割线--------------
基于AVFoundation实现的。
1、效果图
生成界面
扫描界面:
2、环境
ios9.3.2
Xcode7.3(swift 3)
3、生成二维码
~~新建项目~~
A、新建文件:QRCode View.swift,该文件主要用来生成二维码
B、该文件源码内容如下:
import UIKit
/// 生成二维码
class QRCodeView: UIView
{
/**
- logo
- parameter surperImage: 二维码
- parameter subImage: logo
- parameter postRext: logo位置
- returns: 返回加上logo的图片
*/
private func imageViewAddImage(surperImage: UIImage,subImage: UIImage,postRect:CGRect) -> UIImage
{
//// 创建图像
UIGraphicsBeginImageContext(surperImage.size);
//// 设置坐标
surperImage.drawInRect(CGRect(x:0,y:0,width: surperImage.size.width,height: surperImage.size.height));
surperImage.drawInRect(postRect);
//// 返回一个图像基于当前位图图形
let newImage = UIGraphicsGetimageFromCurrentimageContext();
//// 移除当前位图图形
UIGraphicsEndImageContext();
return newImage;
}
/**
调整大小
- parameter ciImage: 待改变的image
- parameter width: 设置比例系数
- returns: 设置比例后的图片
*/
private func SetSize(ciImage: CIImage,_width:CGFloat) -> UIImage
{
let extent = CGRectIntegral(ciImage.extent);
let scale = min(_width / CGRectGetWidth(extent),_width / CGRectGetHeight(extent));
let width = CGRectGetWidth(extent) * scale;
let height = CGRectGetHeight(extent) * scale;
let cs = CGColorSpaceCreateDeviceGray();
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue);
let bitmapRef = CGBitmapContextCreate(nil,Int(width),Int(height),8,cs,bitmapInfo.rawValue);
let context = CIContext(options: [kCIContextUseSoftwareRenderer:(true)]);
let bitmapImage = context.createCGImage(ciImage,fromrect: extent);
CGContextSetInterpolationQuality(bitmapRef,CGInterpolationQuality.None)
CGContextScaleCTM(bitmapRef,scale,scale)
CGContextDrawImage(bitmapRef,extent,bitmapImage);
let scaledImage = CGBitmapContextCreateImage(bitmapRef);
return UIImage(CGImage: scaledImage!);
}
/**
截取logo边角
- parameter cornerRadius: 截取度
- parameter image: 需要截取边角的图片
- returns: 截取边角后的图片
*/
private func ImageAfterCutOutCorner(cornerRadius:CGFloat,image:UIImage) -> UIImage
{
let frame = CGRectMake(0,image.size.width,image.size.height);
UIGraphicsBeginImageContextWithOptions(image.size,false,1.0);
UIBezierPath.init(roundedRect:frame,cornerRadius: cornerRadius).addClip();
image.drawInRect(frame);
let im = UIGraphicsGetimageFromCurrentimageContext();
UIGraphicsEndImageContext();
return im;
}
/**
生成二维码
- parameter urlString: 电话号码
- parameter surperView: image View
- parameter logo: logo的位置
- parameter logoSize: logo的大小
- parameter cornerRadius: 边角裁剪度
- returns: 二维码
*/
class func GenerateQRCode(urlString:String,surperView:UIView,logo:UIImage,logoSize:CGSize,cornerRadius: CGFloat) -> QRCodeView
{
let qrCodeView = QRCodeView();
qrCodeView.frame = CGRect(x: 0,y: 0,width: surperView.frame.size.width,height: surperView.frame.size.height);
//// 该参数代表二维码不可改变
let filter = CIFilter.init(name: "CiqrCodeGenerator");
filter?.setDefaults();
filter?.setValue(urlString.dataUsingEncoding(NSUTF8StringEncoding),forKey: "inputMessage"); //inputMessage 固定写法,代表输入信息 的意思
let ciImage = filter?.outputimage;
let QRImage = qrCodeView.SetSize(ciImage!,_width: surperView.frame.width);
var cornerRadius_1 = cornerRadius;
if (!logo.isEqual(nil))
{
if (cornerRadius_1 < 0)
{
cornerRadius_1 = 0;
}
}
qrCodeView.layer.contents = QRImage.CGImage;
surperView.addSubview(qrCodeView);
return qrCodeView;
}
}
C、在ViewController.swift 文件中调用。
D、在main.storyboard中添加控件:
E、在viewcontroller.swift 做关联:
F、同理,在 viewcontroller.swift 关联按钮的事件
G、关联完成,接着就在viewcontroller.swift中调用创建二维码了
生成二维码,当然是写在这个按钮下啦。 在 F 的函数中写上如下代码:
/**
生成按钮
- parameter sender: nothing
*/
@IBAction func BtnGenerateQRCode(sender: UIButton)
{
label.text = "";
if (textField.text == "")
{
label.font = UIFont.systemFontOfSize(20);
label.text = "电话号码不能为空";
return;
}
textField.resignFirstResponder();/// 取消焦点
// 生成二维码
QRCodeView.GenerateQRCode(textField.text!,surperView: imageView,logo: UIImage(named: "logo")!,logoSize: CGSizeMake(100,100),cornerRadius: CGFloat(1000));
} 同时,在ViewDidLoad方法中写上代码,设置控件属性
/**
窗口加载
*/
override func viewDidLoad()
{
super.viewDidLoad();
label.adjustsFontSizetoFitWidth = true;// 设置自适应
label.text = ""; /// 清空
// Do any additional setup after loading the view,typically from a nib.
}
OK,二维码生成完成~~~
下面是 viewcontroller.swift 的详细源码:
//
// ViewController.swift
// GenerateQRCode
//
// Created by driver on 16/9/7.
// copyright © 2016年 driver. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
/// 提示label
@IBOutlet weak var label: UILabel!
/// 二维码显示框
@IBOutlet weak var imageView: UIImageView!
/// 电话号码输入框
@IBOutlet weak var textField: UITextField!
/**
窗口加载
*/
override func viewDidLoad()
{
super.viewDidLoad();
label.adjustsFontSizetoFitWidth = true;// 设置自适应
label.text = ""; /// 清空
// Do any additional setup after loading the view,typically from a nib.
}
/**
生成按钮
- parameter sender: nothing
*/
@IBAction func BtnGenerateQRCode(sender: UIButton)
{
label.text = "";
if (textField.text == "")
{
label.font = UIFont.systemFontOfSize(20);
label.text = "电话号码不能为空";
return;
}
textField.resignFirstResponder();/// 取消焦点
// 生成二维码
QRCodeView.GenerateQRCode(textField.text!,cornerRadius: CGFloat(1000));
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// dispose of any resources that can be recreated.
}
}
///-----我是分割线--------------------
4、扫描二维码
~~~~ 新建项目~~~
A、扫描,就是在main.storyboard 中添加一个控件:按钮, 然后关联其touch事件。
B、在 Viewcontroller.swift 中,导入的库:
import UIKit import AVFoundationC、
ViewController类继承的有:
UIViewController,AVCaptureMetadataOutputObjectsDelegate代码:
class ViewController: UIViewController,AVCaptureMetadataOutputObjectsDelegateD、viewcontroller类 定义的属性有:
////定义属性
var session: AVCaptureSession?;
var layer: AVCaptureVideoPreviewLayer?;
E、viewDidLoad方法中添加代码:
super.viewDidLoad();
///self.view.backgroundColor = UIColor.lightGrayColor();
self.modalPresentationStyle = .Custom;F、在自己关联的按钮事件函数,源码如下:
////扫描
@IBAction func scanQRcode(sender: AnyObject)
{
self.session = AVCaptureSession();
////
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo);
do
{
let input = try AVCaptureDeviceInput(device: device);
if (self.session!.canAddInput(input))
{
self.session!.addInput(input);
}
////输出
let output = AVCaptureMetadataOutput();
output.setMetadataObjectsDelegate(self,queue: dispatch_get_main_queue());
if (self.session!.canAddOutput(output))
{
self.session!.addOutput(output)
output.MetadataObjectTypes = [AVMetadataObjectTypeQRCode];
}
////添加图层
self.layer = AVCaptureVideoPreviewLayer(session:self.session!);
self.layer!.frame = self.view.frame;
self.view.layer.addSublayer(self.layer!);
//// 开始扫描
self.session?.startRunning();
}
catch let error as NSError
{
print(error);
}
}
F、实现 AVCaptureMetadataOutputObjectsDelegate 委托中的方法:
////委托
@objc func captureOutput(captureOutput: AVCaptureOutput!,didOutputMetadataObjects MetadataObjects: [AnyObject]!,fromConnection connection: AVCaptureConnection!)
{
let stringValue:String?;
if (MetadataObjects.count > 0)
{
let MetadataObject = MetadataObjects[0] as! AVMetadataMachineReadableCodeObject;
////
stringValue = MetadataObject.stringValue;
if (nil != stringValue) ////这里捕捉到二维码
{
self.session!.stopRunning();
//// 移除图层
self.layer!.removeFromSuperlayer();
////启动拨号~~
UIApplication.sharedApplication().openURL(NSURL(string: "tel://\(stringValue)")!);
// let alertView = UIAlertController(title: "二维码",message: stringValue,preferredStyle: .Alert);
// let action = UIAlertAction(title: "OK",style: UIAlertActionStyle.Default,handler: nil);
// alertView.addAction(action);
////显示提示框
// self.presentViewController(alertView,animated: true,completion:nil);
}
else
{
let alertView = UIAlertController(title: "二维码",message: "没有扫描到二维码",preferredStyle: .Alert);
let action = UIAlertAction(title: "OK",handler: nil);
alertView.addAction(action);
////显示提示框
self.presentViewController(alertView,completion:nil);
}
}
}
import UIKit
import AVFoundation
class ViewController: UIViewController,AVCaptureMetadataOutputObjectsDelegate
{
////定义属性
var session: AVCaptureSession?;
var layer: AVCaptureVideoPreviewLayer?;
////方法
override func viewDidLoad()
{
super.viewDidLoad();
///self.view.backgroundColor = UIColor.lightGrayColor();
self.modalPresentationStyle = .Custom;
}
////扫描
@IBAction func scanQRcode(sender: AnyObject)
{
self.session = AVCaptureSession();
////
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo);
do
{
let input = try AVCaptureDeviceInput(device: device);
if (self.session!.canAddInput(input))
{
self.session!.addInput(input);
}
////输出
let output = AVCaptureMetadataOutput();
output.setMetadataObjectsDelegate(self,queue: dispatch_get_main_queue());
if (self.session!.canAddOutput(output))
{
self.session!.addOutput(output)
output.MetadataObjectTypes = [AVMetadataObjectTypeQRCode];
}
////添加图层
self.layer = AVCaptureVideoPreviewLayer(session:self.session!);
self.layer!.frame = self.view.frame;
self.view.layer.addSublayer(self.layer!);
//// 开始扫描
self.session?.startRunning();
}
catch let error as NSError
{
print(error);
}
}
////委托
@objc func captureOutput(captureOutput: AVCaptureOutput!,completion:nil);
}
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
}