美文网首页IOS开发路上的故事iOS学习
iOS开发中的常用实用小功能

iOS开发中的常用实用小功能

作者: 慌莫染 | 来源:发表于2018-10-10 11:49 被阅读22次

在一个项目开发中,少不了一些小功能的应用。比如清理缓存,二维码,第三方支付等。那么在接下来的篇幅中,就介绍些类似小功能的应用

清理缓存
二维码生成和扫描
国际化
支付宝支付
物理仿真
富文本
语音合成
重力感应:摇一摇

一:清理缓存

//清理缓存:阅读类、购物类等APP的标配功能
//清理缓存的步骤:1.计算缓存文件的大小 2.分别清除缓存文件夹下的每个子文件
具体实现如一下代码(以下是沙盒目录下的缓存清楚方法)

//获取缓存文件的路径---沙盒目录下Library文件夹下的Cache文件夹
        let cachePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory
            .CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).first
    //定义变量,用于计算所有子文件的大小
    var size = Double()
    //获取Cache文件夹下的所有文件
    //NSFileManager是系统的文件管理类
    let fileArray = NSFileManager.defaultManager().subpathsAtPath(cachePath!)
    //遍历数组,计算每个子文件的大小
    for fileName in fileArray!{
        //拼接每个子文件的路径
        let filePath = cachePath?.stringByAppendingString("/\(fileName)")
        //获取每个子文件的属性
       
        let fileAttribute = try! NSFileManager.defaultManager().attributesOfItemAtPath(filePath!)
        
        print(fileAttribute)
        
        for (fileAtt,fileSize) in fileAttribute{
            if fileAtt == NSFileSize{
                //计算大小
                size = size + fileSize.doubleValue//单位为字节
            }
        }
    }
    //提示框---保留小数点后两位,单位为MB
    let message = String(format: "当前有%.2fM缓存",  size / Double(1024*1024))
    
    let alertVc = UIAlertController.init(title: "提示", message: message, preferredStyle: .Alert)
    let alertAction = UIAlertAction.init(title: "确定", style: .Default) { (action) -> Void in
        for fileName in fileArray!{
            let filePath = cachePath?.stringByAppendingString("/\(fileName)")
            //判断当前路径下的文件是否存在
            if NSFileManager.defaultManager().fileExistsAtPath(filePath!){
                //进行清除
                do{
                    try NSFileManager.defaultManager().removeItemAtPath(filePath! )
                    
                }catch{
                    
                }
                
                
                
            }
        }
    }
    
    let cancelAction = UIAlertAction.init(title: "取消", style: .Default, handler: nil)
    alertVc.addAction(alertAction)
    alertVc.addAction(cancelAction)
    self.presentViewController(alertVc, animated: true, completion: nil)

如果我们用了SDWebimage来加载网络图片,那么它会创建自己的网络图片等缓存文件夹。此时我们清理缓存可以使用下面代码

//获取由SDWebImage缓存的文件的大小
        let size = SDImageCache.sharedImageCache().getSize()
        //清理内存中的缓存
        SDImageCache.sharedImageCache().clearMemory()
        //清理沙盒目录下的缓存
        SDImageCache.sharedImageCache().clearDisk()
        SDImageCache.sharedImageCache().cleanDisk()

二:二维码的生成和扫描

二维码的生成和扫描可以用系统的CIFilter类,也可以使用第三方ZBar。各有利弊。使用系统的好处就是免去导入第三方库的繁琐,也可以使得程序瘦身。使用ZBar的好处就是代码简单
以下先介绍系统的方法
二维码的生成

    let filter = CIFilter(name: "CIQRCodeGenerator")
    //设置二维码需要携带的信息
    let str = "http://www.baidu.com"
    let data = str.dataUsingEncoding(NSUTF8StringEncoding)
    //将信息设置给filter-数据类型的data
    filter?.setValue(data, forKey: "inputMessage")
    //获取输出信息
    let output = filter?.outputImage
    
    //转化成图片
    let image = UIImage(CIImage: output!)
    //显示二维码图片
    let imageview = UIImageView.init(frame: CGRectMake(100, 100, 100, 100))
    imageview.image = image
    
    self.view.addSubview(imageview)

二维码的扫描要导入AVFoundation框架,同时要遵循AVCaptureMetadataOutputObjectsDelegate协议,以实现扫描完成之后的回调
代码如下
属性

//拍摄会话
var captureSession:AVCaptureSession!
//显示图层
var previerLayer:AVCaptureVideoPreviewLayer!```

扫描行为


//开始扫描
    @IBAction func scanAction(sender: UIButton) {
        //调用摄像头
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        //设置输入输出信息
        
        do{
            //输入:主要为了检测是否有摄像设备
            let input =  try AVCaptureDeviceInput(device: device)
            //输出:主要为了获取扫描的结果
            let output = AVCaptureMetadataOutput()
            //设置代理(设置队列为主队列,主要是为了扫描到结果后能立马在设备中显示出来)
            output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
            //初始化回话
            self.captureSession = AVCaptureSession()
            //将输入输出添加到会话中
            self.captureSession.addInput(input)
            self.captureSession.addOutput(output)
            
            //创建显示图层
            self.previerLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
            //设置大小
            self.previerLayer.frame = self.view.bounds
            self.view.layer.addSublayer(self.previerLayer)
            
            //开启会话
            self.captureSession.startRunning()
            
            
        }catch{
            print("检测不到设备")
        }
        
    }

完成之后的回调

//扫描完成之后的回调,metadataObjects表示扫描的结果,返回的数组
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        //停止会话
        self.captureSession.stopRunning()
        //移除显示图层
        self.previerLayer.removeFromSuperlayer()
        //获取结果
        if metadataObjects.count > 0{
            let object = metadataObjects.first as! AVMetadataMachineReadableCodeObject
            print(object.stringValue)
        }
        
    }

第三方ZBar的二维码生成和扫描
ZBarSDK是常用的二维码生成和扫描的第三方包括ZBarSDK和ZXingSDK,后者已经停止更新。ZBarSDK封装自系统的CIFilter(滤镜处理器)和AVCapturSession(会话)
代码如下:

@IBOutlet weak var QRimageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //二维码生成
        /*
        para1:二维码携带的信息
        para2:二维码的清晰度,数值越大越清晰(0~500)
        
        */
        
        QRimageView.image = QRCodeGenerator.qrImageForString("http://www.baidu.com", imageSize: 400)
        
        
    }
    
    //扫描
    @IBAction func scanAction(sender: UIButton) {
        /*
        para1:isQRCode:如果设置为true的话,表示关闭二维码扫描,只扫描条形码
        para2:result:扫描的结果
        */
        let customVC = CustomViewController(isQRCode: false) { (result, isSuccess) -> Void in
            if isSuccess{
                print("0")
                //实际项目中,扫描得到结果之后一般都会跳转页面,将result进行传值
            }else{
                print("22")
            }
        }
        
        self.presentViewController(customVC, animated: true, completion: nil)
    }

三:国际化

以一个提示框的语言选择作为例子。先创建两个不遵循任何类的文件,用来保存特定key对应的value值

英语环境下的值

//key = value
"TITLE" = "title";
"MESSAGE" = "message";
"CONFORM" = "conform";
"CANCEL" = "cancel";

中文环境下的值

"TITLE" = "标题";
"MESSAGE" = "信息";
"CONFORM" = "确定";
"CANCEL" = "取消";

通过系统的语言设置去取得相应的key值

//根据系统的语音匹配对应的提示框
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let alertVC = UIAlertController(title: NSLocalizedString("TITLE", comment: ""), message: NSLocalizedString("MESSAGE", comment: ""), preferredStyle: .Alert)
        let aleatAction = UIAlertAction(title: NSLocalizedString("CONFORM", comment: ""), style: .Default, handler: nil)
        let cancleAction = UIAlertAction(title: NSLocalizedString("CANCEL", comment: ""), style: .Default, handler: nil)
        alertVC.addAction(aleatAction)
        alertVC.addAction(cancleAction)
        self.presentViewController(alertVC, animated: true, completion: nil)
    }

四:支付宝支付

首先加入阿里的第三方AliSDK,这里不再赘述。代码也比较简单。如下:

/*
支付宝的支付流程
1.用户生成订单
2.用户选择支付宝支付(调取支付宝客户端或者网页支付,将订单上传到支付宝服务端)
3.支付宝服务端处理支付结果并将结果返回客户端

*/
 @IBAction func payAction(sender: UIButton) {
        //创建订单
        let order = Order()
        //商户ID:商户在支付宝签约时,支付宝为商户分配的唯一标识号(以2088开头的16位纯数字)
        order.partner = partner
        //账户ID:卖家支付宝账号对应的支付宝唯一用户号(以2088开头的16位纯数字),订单支付金额将打入该账户,一个partner可以对应多个seller_id
        order.sellerID = seller
        //订单号://商户网站商品对应的唯一订单号.一般由后台生成,是随机的
        order.outTradeNO = "20161026100856"
        //资金总额:该笔订单的资金总额,单位为RMB(Yuan)。取值范围为[0.01,100000000.00],精确到小数点后两位。
        order.totalFee = "1000023354.21"
        //交易说明:商品的标题/交易标题/订单标题/订单关键字等。
        order.subject = "急急急级急急急急急急急"
        //商品的具体描述:对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
        order.body = "花式叽叽叽叽"
        
        
        //获取商品的全部描述
        let orderDes = order.description
        //开始使用私钥进行签名(在客服端执行,实际项目中,建议将签名放在后台做,数据传输更安全)
        let signer = CreateRSADataSigner(privateKey) as! RSADataSigner
        //打包签名信息
        let signerStr = signer.signString(orderDes)
        //拼接商品信息
        let orderStr = String(format: "ServerPayDemo://localhost?ordername=%@&price=%@“", orderDes,signerStr,"RSA")
        //发起支付请求
        /*
        para1:
        para2:URL scheme:回调的唯一标识
        para3:支付完成之后的结果回调
        */
        AlipaySDK.defaultService().payOrder(orderStr, fromScheme: "AlipayHector") { (result) -> Void in
            print(result)
        }
    }

五:物理仿真

物理仿真用到的是系统的UIDynamicAnimator仿真者类,同时声明各种仿真行为,如UIDynamicItemBehavior,UIGravityBehavior,UICollisionBehavior,UISnapBehavior
将仿真行为添加到仿真者上

dynamicAnimator.addBehavior(dynamicItemBehavior)

同时,仿真行为也需要加入对象,其意义为要使得那些对象去执行此仿真行为

dynamicItemBehavior.addItem(imageView)

具体代码如下

    var dynamicAnimator:UIDynamicAnimator!
    //现实行为
    var dynamicItemBehavior:UIDynamicItemBehavior!
    //重力行为
    var gravityBehavior:UIGravityBehavior!
    //碰撞行为
    var collisionBehavior:UICollisionBehavior!
    //吸附行为
    var snapBehavior:UISnapBehavior!
    //吸附行为作用的item
    var mainImageView:UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //dynamic1()
        dynamic2()
    }
    
    //点击屏幕的时候,创建一个imageView,让其遵循现实、重力、碰撞行为
    func dynamic1(){
        //创建仿真者
        dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
        //创建现实行为
        dynamicItemBehavior = UIDynamicItemBehavior(items: [])
        dynamicItemBehavior.elasticity = 1
        //创建重力行为
        gravityBehavior = UIGravityBehavior(items: [])
        //创建碰撞行为
        collisionBehavior = UICollisionBehavior(items: [])
        //开启刚性碰撞
        collisionBehavior.translatesReferenceBoundsIntoBoundary = true
        //将行为天机到仿真者中
        dynamicAnimator.addBehavior(dynamicItemBehavior)
        dynamicAnimator.addBehavior(gravityBehavior)
        dynamicAnimator.addBehavior(collisionBehavior)
        
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
  
        for _ in 0...5{
            let x = CGFloat(arc4random()%300)
            let y = CGFloat(arc4random()%600)
            let size = CGFloat(arc4random()%50 + 5)
            let imageArray = ["bird1","bluebird1","pig1","pig_44","yellowbird1","shelf1"]
            let index = Int(arc4random()%6)
            let imageView = UIImageView(frame: CGRectMake(x, y, size, size))
            imageView.image = UIImage.init(named: imageArray[index])
            self.view.addSubview(imageView)
                
            //让imageView遵循各种行为
            dynamicItemBehavior.addItem(imageView)
            collisionBehavior.addItem(imageView)
            gravityBehavior.addItem(imageView)
        }

        //移除到仿真者上所有的行为
        dynamicAnimator.removeAllBehaviors()
        //获取手指点击的位置
        let touch = (touches as NSSet).anyObject()
        let point = touch?.locationInView(self.view)
        //初始化吸附行为
        /*
        para1:需要吸附行为作用的空间
        para2:需要移动的位置
        */
        snapBehavior = UISnapBehavior(item: mainImageView, snapToPoint: point!)
        //设置弹跳幅度
        snapBehavior.damping = 0.6
        //将吸附行为添加到仿真者中
        dynamicAnimator.addBehavior(snapBehavior)
    }
    
    func dynamic2(){
        mainImageView = UIImageView(frame: CGRectMake(0, 0, 100, 100))
        mainImageView.image = UIImage.init(named: "69.jpg")
        self.view.addSubview(mainImageView)
        //初始化仿真者
        dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
        
        
    }

六:富文本

override func viewDidLoad() {
        super.viewDidLoad()
        //富文本 是字符串的一种,可以对同一字符串中的字符进行区别设置样式
        //设置文字
        self.setText()
        //设置段落
        //self.setParagraph()
        //设置图片
        self.setImage()
    }

    func setText(){
        let label1 = UILabel.init(frame: CGRectMake(100, 100, 300, 50))
        label1.textColor = UIColor.blackColor()
        label1.font = UIFont.systemFontOfSize(12)
        self.view.addSubview(label1)
        let str1 = "¥300/位"
        //初始化富文本
        let attStr = NSMutableAttributedString(string: str1)
        //分别设置单一的属性
        //设置字体大小
        //attStr.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(30), range: NSMakeRange(0, 4))
        //设置字体颜色
        //attStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(1, 4))
        //同时设置
        attStr.addAttributes([NSFontAttributeName:UIFont.systemFontOfSize(30),NSForegroundColorAttributeName:UIColor.orangeColor()], range: NSMakeRange(0, 4))
        //赋值
        label1.attributedText = attStr
    }
    func setParagraph(){
        let label2 = UILabel.init(frame: CGRectMake(100, 200, 300, 400))
        label2.textColor = UIColor.orangeColor()
        label2.font = UIFont.systemFontOfSize(14)
        //设置折行方式
        label2.numberOfLines = 0
        label2.lineBreakMode = .ByWordWrapping
        self.view.addSubview(label2)
        let str = "前段时间锻炼身体胃出血的事情,每天想着这个事情,害怕有什么大问题!这周一才预约下周一去做胃镜检查,又要担心好几天啊!我在思考如果真有大病,医院这种制度得耽误多少病人,因为这种制度而耽误多少人的最佳治疗时间?我们还是要多读书的,因为最近动物考古学家一行在饭店吃饭,点的羊腿中赫然发现猪骨,愤而与店家对质(你们知道我们是干什么的吗?我们连一根毛都知道出自什么动物身上),最后店家给免单了(我怎么就没这本事呢^_^)!"
        //初始化富文本
        let attStr = NSMutableAttributedString(string: str)
        //初始化段落样式
        let paraStyle = NSMutableParagraphStyle()
        //设置行间距,返回类型都为CGFloat类型
        paraStyle.lineSpacing = 20.0
        //段落间距
        paraStyle.paragraphSpacing = 50.0
        //设置首行缩进的距离
        paraStyle.firstLineHeadIndent = 40.0
        //设置出首行之外的行缩进的距离
        paraStyle.headIndent = 10.0
        //将段落样式赋值给富文本
        attStr.addAttributes([NSParagraphStyleAttributeName:paraStyle], range: NSMakeRange(0, (str as NSString).length))
        label2.attributedText = attStr
        
    }
    func setImage(){
        let label3 = UILabel(frame:CGRectMake(100,200,300,400))
        label3.numberOfLines = 0
        label3.lineBreakMode = .ByWordWrapping
        self.view.addSubview(label3)
        label3.text = "前段时间锻炼身体胃出血的事情,每天想着这个事情,害怕有什么大问题!这周一才预约下周一去做胃镜检查,又要担心好几天啊!我在思考如果真有大病,医院这种制度得耽误多少病人,因为这种制度而耽误多少人的最佳治疗时间?我们还是要多读书的,因为最近动物考古学家一行在饭店吃饭,点的羊腿中赫然发现猪骨,愤而与店家对质(你们知道我们是干什么的吗?我们连一根毛都知道出自什么动物身上),最后店家给免单了(我怎么就没这本事呢^_^)!"
        
       let attStr = label3.attributedText?.mutableCopy()
        //插入图片
        let image = UIImage.init(named: "bird1")
        //初始化图文混拍的类
        let attachment = NSTextAttachment()
        //设置图片大小
        attachment.bounds = CGRectMake(0, 0, 30, 30)
        //将图片赋给图文混排的类
        attachment.image = image
        //通过图文混排的类初始化一个新的富文本字符串
        let attStr1 = NSAttributedString(attachment: attachment)
        //将图片插入到原来的文字中
        attStr?.insertAttributedString(attStr1, atIndex: 50)
        label3.attributedText = attStr as! NSMutableAttributedString
    }

七:语音合成

语音合成有系统现成的类AVSpeechSynthesizer,同时讯飞也有强大的语言合成的第三方库。这里先介绍系统的语言合成,非常简单。如下:

//初始化语音播放器
        let speeech = AVSpeechSynthesizer()
        //设置
        let utterance = AVSpeechUtterance(string: "鹏吉吉个小吉吉")
        //设置语速,数值越大,频率越大
        utterance.rate = 0.5
        //开始播放
        speeech.speakUtterance(utterance)

讯飞语音:

//待写

八:重力感应:摇一摇

重力感应用到三个方法motionBegan,motionEnded,motionCancelled
具体代码也非常简单

 //重力感应:摇一摇
    override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) {
        print("摇动开始")
        //摇一摇的过程中一般伴随着震动或者声音
        //短效音频的实现
        //声明一个系统声音ID
        var soundID:SystemSoundID = 1
        //设置播放的资源
        /*
        para1:本地短效音频资源的路径
        para2:系统声音ID的地址
        */
        let path = NSBundle.mainBundle().pathForResource("shake", ofType: "wav")
        AudioServicesCreateSystemSoundID(NSURL(fileURLWithPath: path!),&soundID)
        //设置震动效果
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
        //设置声音提示
        AudioServicesPlaySystemSound(soundID)
    }
    override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) {
        //摇动结束的事件
        print("摇动结束")
    }
    override func motionCancelled(motion: UIEventSubtype, withEvent event: UIEvent?) {
        //摇动取消的事件
        print("摇动取消")
    }

相关文章

网友评论

    本文标题:iOS开发中的常用实用小功能

    本文链接:https://www.haomeiwen.com/subject/gzrpaftx.html