iOS

ios 二维码界面和代码实现,优化卡顿

2019-06-10  本文已影响0人  若风_412d

https://www.cnblogs.com/pretty-guy/p/4255359.html

原理:

AVCaptureSession 管理者
input 读取 二维码
output输出 二维码的内容
AVCaptureVideoPreviewLayer 界面

代理方法输出字符串。

逻辑

1.判断相机,以及拒绝打开相机的操作
https://www.jianshu.com/p/c71c12da3bb1
2

界面

导航条透明,状态栏白色,返回按钮白色:

viewWillAppear设置,
viewwilldisappear 重新设置为正常;

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    
    
    [self.navigationController.navigationBar setTranslucent:YES];//设置透明度

    //    //颜色字体
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:kWhiteColor,NSFontAttributeName:[UIFont boldSystemFontOfSize:17]};
    
    
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"icon_back"] forState:UIControlStateNormal];
    button.size = CGSizeMake(70, 44);
    [button setImageEdgeInsets:UIEdgeInsetsMake(5, 5, 5, 0)];//上左下右
    button.imageView.contentMode = UIViewContentModeScaleAspectFit;
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    [button addTarget:self action:@selector(backBtn) forControlEvents:UIControlEventTouchUpInside];
//这个地方就是self.navigationItem,不是controuler,好像是系统的,上边的那个返回图片无效,有空在考虑原因。
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    //状态栏
//1.在info.plist中添加View controller-based status bar appearance,值为NO


    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    
    [self.navigationController.navigationBar setTranslucent:NO];//设置透明度

    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;//状态栏
    //颜色字体
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:kNavTitleColor,NSFontAttributeName:[UIFont boldSystemFontOfSize:17]};
    
}
扫描线:

动画有个属性UIViewAnimationOptionRepeat是反复执行的意思
//还有一种是加timer的,也是要设置,进入后台timer不停的。


_line.frame = CGRectMake(0, 0, scanSize.width, 18);//扫描线的imageview
    
    /* 添加动画 */
    
  
    [UIView animateWithDuration:2.5 delay:0.0 options:UIViewAnimationOptionRepeat animations:^{//反复执行
        
        
        _line.frame = CGRectMake(0, scanSize.height-18, scanSize.width, 10);
        
        
    } completion:nil];

动画进入后台之后会消失.那么就让它进入激活状态重新打开动画

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayground) name:UIApplicationDidBecomeActiveNotification object:nil];
}
-(void)appDidEnterPlayground{
    [self.heroBtn.layer removeAllAnimations];//移除动画
     [self.heroBtn.layer addAnimation:[self groupAnimation] forKey:nil];//添加动画
}

但是这样的话,只要app进过的二维码的界面,已有不管在那个地方,只要重新进入前端都会刷新一下这个动画。挺尴尬,未完待续。

卡顿

这里二维码相关的设置设置完以后我们就要启动扫描了,这里一般是直接调方法 [self.captureSession startRunning]来开始扫描,但问题就在这里,这个方法是会阻塞主线程的直到启动完成,api说明里是有注明的,所以我们就不能这样用,会照成卡顿,我们要放到子线程去启动就行了,顺便做一个加载动画,跟微信的做法保持一致
时间有限,动画就不做了,下面链接里有

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//
        [[KJZbar manager] startRunning];
       // [_kBar startRunning];
    });

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [[KJZbar manager] stopRunning];
    });

https://blog.csdn.net/weixin_33670786/article/details/87133426

//下面的删了。出现在连续两个界面都是背景透明的情况会很卡,但是这个东西,需求删掉了。

写到子线程中,界面不卡了,背景延迟,才出来,于是把二维码做成单利,好多了

+ (id)manager{
   
   static KJZbar * singleton = nil;
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
       singleton = [[KJZbar alloc] init];
   });
   return singleton;
   
   //        DLZBar * singleton;
   //        singleton = [[DLZBar alloc] init];
   //    return singleton;
   
}

ios 打开关闭手电筒

//yes 开, no是关
- (void)turnTorchOn:(bool)on{
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch] && [device hasFlash]){
            
            [device lockForConfiguration:nil];
            if (on) {
                [device setTorchMode:AVCaptureTorchModeOn];
                [device setFlashMode:AVCaptureFlashModeOn];
                on = YES;
            } else {
                [device setTorchMode:AVCaptureTorchModeOff];
                [device setFlashMode:AVCaptureFlashModeOff];
                on = NO;
            }
            [device unlockForConfiguration];
        }
    }
}

如果要在多个界面打开手电,写一个block回调,执行viewDidAppear。willAppear打不开手电。

- (void)viewDidAppear:(BOOL)animated{
   [super viewDidAppear:animated];
   //手电筒的回调
   if (_lightState) {
       [self turnTorchOn:YES];
   }else{
       [self turnTorchOn:NO];
   }

}
上一篇 下一篇

猜你喜欢

热点阅读