~~~写在前面的话~~~

我之前打算做一个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 AVFoundation
C、

ViewController类继承的有:

UIViewController,AVCaptureMetadataOutputObjectsDelegate
代码:
class ViewController: UIViewController,AVCaptureMetadataOutputObjectsDelegate
D、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);
            }
        }
    }


G、详细源码:


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()
      
    }


}

swift生成二维码,扫描二维码的更多相关文章

  1. 手对手的教你用canvas画一个简单的海报的方法示例

    企业的广告投入开始从电视等传统媒体向基于圈层文化的新媒体精准营销转移,很多人都想制作一张属于自己的海报,本文介绍了手对手的教你用canvas画一个简单的海报的方法示例,感兴趣的可以了解一下

  2. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. iOS Swift上弃用后Twitter.sharedInstance().session()?. userName的替代方案

    解决方法如果您仍在寻找解决方案,请参阅以下内容:

  4. 使用Fabric SDK iOS访问Twitter用户时间线

    我试图在这个问题上挣扎两天.我正在使用FabricSDK和Rest工具包,试图为Twitter使用不同的RestAPIWeb服务.我可以使用具有authTokenSecret,authToken和其他值的会话对象的TWTRLogInButton成功登录.当我尝试获取用户时间线时,我总是得到失败的响应,作为:{“errors”:[{“code”:215,“message”:“BadAuthentic

  5. ios – 如何从Apple Watch调用iPhone上定义的方法

    有没有办法从Watchkit扩展中调用iPhone上的类中定义的方法?根据我的理解,目前在Watchkit和iPhone之间进行本地通信的方法之一是使用NSUserDefaults,但还有其他方法吗?

  6. ios – 如何将视频从AVAssetExportSession保存到相机胶卷?

    在此先感谢您的帮助.解决方法只需使用session.outputURL=…

  7. ios – 使用AVCaptureSession sessionPreset = AVCaptureSessionPresetPhoto拉伸捕获的照片

    解决方法所以我解决了我的问题.这是我现在使用的代码,它工作正常:…重要的输出imagaView:一些额外的信息:相机图层必须是全屏,并且outputimageView也必须是.我希望这些对某些人来说也是有用的信息.

  8. 我可以在iOS中自定义Twitter工具包的登录按钮吗?

    我已经下载了Twitter工具包框架并添加了用Twitter登录的代码.但是,我不希望登录按钮看起来像那样.我想要一个用于登录的自定义按钮.我能这样做吗?我只想使用这个框架,因为这也适用于iOS系统帐户.解决方法根据document:在按下按钮中添加代码:Objective-C的迅速

  9. ios – AVCaptureSession条形码扫描

    解决方法以下是我所拥有的项目代码示例,可以帮助您走上正确的轨道

  10. ios – 如何在Watch OS 2中引用不支持的框架

    有没有办法将框架链接到扩展名?

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部