chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:35:01 +08:00
commit a2e318a963
2974 changed files with 158180 additions and 0 deletions
@@ -0,0 +1,40 @@
//
// TLScannerViewController.h
// TLChat
//
// Created by 李伯坤 on 16/2/24.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIkit.h>
#import "TLScannerButton.h"
@class TLScannerViewController;
@protocol TLScannerDelegate <NSObject>
@optional
- (void)scannerViewControllerInitSuccess:(TLScannerViewController *)scannerVC;
- (void)scannerViewController:(TLScannerViewController *)scannerVC
initFailed:(NSString *)errorString;
- (void)scannerViewController:(TLScannerViewController *)scannerVC
scanAnswer:(NSString *)ansStr;
@end
@interface TLScannerViewController : UIViewController
@property (nonatomic, assign) TLScannerType scannerType;
@property (nonatomic, assign) id<TLScannerDelegate>delegate;
@property (nonatomic, assign, readonly) BOOL isRunning;
- (void)startCodeReading;
- (void)stopCodeReading;
+ (void)scannerQRCodeFromImage:(UIImage *)image ans:(void (^)(NSString *ansStr))ans;
@end
@@ -0,0 +1,258 @@
//
// TLScannerViewController.m
// TLChat
//
// Created by 李伯坤 on 16/2/24.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLScannerViewController.h"
#import "TLScannerView.h"
#import "TLScannerBackgroundView.h"
#import <AVFoundation/AVFoundation.h>
@interface TLScannerViewController () <AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic, strong) UILabel *introudctionLabel;
@property (nonatomic, strong) TLScannerView *scannerView;
@property (nonatomic, strong) TLScannerBackgroundView *scannerBGView;
@property (nonatomic, strong) AVCaptureSession *scannerSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@end
@implementation TLScannerViewController
+ (void)scannerQRCodeFromImage:(UIImage *)image ans:(void (^)(NSString *ansStr))ans
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSData *imageData = (UIImagePNGRepresentation(image) ? UIImagePNGRepresentation(image) :UIImageJPEGRepresentation(image, 1));
CIImage *ciImage = [CIImage imageWithData:imageData];
NSString *ansStr = nil;
if (ciImage) {
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:[CIContext contextWithOptions:nil] options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray *features = [detector featuresInImage:ciImage];
if (features.count) {
for (CIFeature *feature in features) {
if ([feature isKindOfClass:[CIQRCodeFeature class]]) {
ansStr = ((CIQRCodeFeature *)feature).messageString;
break;
}
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
ans(ansStr);
});
});
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:self.introudctionLabel];
[self.view addSubview:self.scannerView];
[self.view addSubview:self.scannerBGView];
[self.view.layer insertSublayer:self.videoPreviewLayer atIndex:0];
[self p_addMasonry];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.scannerSession) {
if (_delegate && [_delegate respondsToSelector:@selector(scannerViewControllerInitSuccess:)]) {
[_delegate scannerViewControllerInitSuccess:self];
}
}
else {
if (_delegate && [_delegate respondsToSelector:@selector(scannerViewController:initFailed:)]) {
[_delegate scannerViewController:self initFailed:@"相机初始化失败"];
}
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self.scannerSession isRunning]) {
[self stopCodeReading];
}
}
#pragma mark - Public Methods -
- (void)setScannerType:(TLScannerType)scannerType
{
if (_scannerType == scannerType) {
return;
}
_scannerType = scannerType;
CGFloat width = 0;
CGFloat height = 0;
if (scannerType == TLScannerTypeQR) {
[self.introudctionLabel setText:@"将二维码/条码放入框内,即可自动扫描"];
width = height = SCREEN_WIDTH * 0.7;
}
else if (scannerType == TLScannerTypeCover) {
[self.introudctionLabel setText:@"将书、CD、电影海报放入框内,即可自动扫描"];
width = height = SCREEN_WIDTH * 0.85;
}
else if (scannerType == TLScannerTypeStreet) {
[self.introudctionLabel setText:@"扫一下周围环境,寻找附近街景"];
width = height = SCREEN_WIDTH * 0.85;
}
else if (scannerType == TLScannerTypeTranslate) {
width = SCREEN_WIDTH * 0.7;
height = 55;
[self.introudctionLabel setText:@"将英文单词放入框内"];
}
[self.scannerView setHiddenScannerIndicator:scannerType == TLScannerTypeTranslate];
[UIView animateWithDuration:0.3 animations:^{
[self.scannerView mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(width);
make.height.mas_equalTo(height);
}];
[self.view layoutIfNeeded];
}];
// rect值范围0-1,基准点在右上角
CGRect rect = CGRectMake(self.scannerView.y / SCREEN_HEIGHT, self.scannerView.x / SCREEN_WIDTH, self.scannerView.height / SCREEN_HEIGHT, self.scannerView.width / SCREEN_WIDTH);
[self.scannerSession.outputs[0] setRectOfInterest:rect];
if (!self.isRunning) {
[self startCodeReading];
}
}
- (void)startCodeReading
{
[self.scannerView startScanner];
[self.scannerSession startRunning];
}
- (void)stopCodeReading
{
[self.scannerView stopScanner];
[self.scannerSession stopRunning];
}
- (BOOL)isRunning
{
return [self.scannerSession isRunning];
}
#pragma mark - Delegate -
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count > 0) {
[self stopCodeReading];
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
if (_delegate && [_delegate respondsToSelector:@selector(scannerViewController:scanAnswer:)]) {
[_delegate scannerViewController:self scanAnswer:obj.stringValue];
}
}
}
#pragma mark - Private Methods -
- (void)p_addMasonry
{
[self.scannerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.centerY.mas_equalTo(self.view).mas_offset(-55);
make.width.and.height.mas_equalTo(0);
}];
[self.scannerBGView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
}];
[_scannerBGView addMasonryWithContainView:self.scannerView];
[self.introudctionLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.width.mas_equalTo(self.view);
make.top.mas_equalTo(self.scannerView.mas_bottom).mas_offset(30);
}];
}
#pragma mark - Getter -
- (AVCaptureSession *)scannerSession
{
if (_scannerSession == nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error) { // 没有摄像头
return nil;
}
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
if ([session canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {
[session setSessionPreset:AVCaptureSessionPreset1920x1080];
}
else if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
[session setSessionPreset:AVCaptureSessionPreset1280x720];
}
else {
[session setSessionPreset:AVCaptureSessionPresetPhoto];
}
if ([session canAddInput:input]) {
[session addInput:input];
}
if ([session canAddOutput:output]) {
[session addOutput:output];
}
[output setMetadataObjectTypes:@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode]];
_scannerSession = session;
}
return _scannerSession;
}
- (AVCaptureVideoPreviewLayer *)videoPreviewLayer
{
if (_videoPreviewLayer == nil) {
_videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.scannerSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPreviewLayer setFrame:self.view.layer.bounds];
}
return _videoPreviewLayer;
}
- (UILabel *)introudctionLabel
{
if (_introudctionLabel == nil) {
_introudctionLabel = [[UILabel alloc] init];
[_introudctionLabel setBackgroundColor:[UIColor clearColor]];
[_introudctionLabel setTextAlignment:NSTextAlignmentCenter];
[_introudctionLabel setFont:[UIFont systemFontOfSize:12.0]];
[_introudctionLabel setTextColor:[UIColor whiteColor]];
}
return _introudctionLabel;
}
- (TLScannerView *)scannerView
{
if (_scannerView == nil) {
_scannerView = [[TLScannerView alloc] init];
}
return _scannerView;
}
- (TLScannerBackgroundView *)scannerBGView
{
if (_scannerBGView == nil) {
_scannerBGView = [[TLScannerBackgroundView alloc] init];
}
return _scannerBGView;
}
@end
@@ -0,0 +1,18 @@
//
// TLScanningViewController.h
// TLChat
//
// Created by 李伯坤 on 16/2/25.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLViewController.h"
@interface TLScanningViewController : TLViewController
/**
* 禁用底部工具栏(默认NO,若开启,将只支持扫码)
*/
@property (nonatomic, assign) BOOL disableFunctionBar;
@end
@@ -0,0 +1,283 @@
//
// TLScanningViewController.m
// TLChat
//
// Created by 李伯坤 on 16/2/25.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLScanningViewController.h"
#import "TLScannerViewController.h"
#import "TLWebViewController.h"
#import "TLScannerButton.h"
#import "TLMyQRCodeViewController.h"
#define HEIGHT_BOTTOM_VIEW 82
@interface TLScanningViewController () <TLScannerDelegate>
@property (nonatomic, assign) TLScannerType curType;
@property (nonatomic, strong) TLScannerViewController *scanVC;
@property (nonatomic, strong) UIBarButtonItem *albumBarButton;
@property (nonatomic, strong) UIButton *myQRButton;
@property (nonatomic, strong) UIView *bottomView;
@property (nonatomic, strong) TLScannerButton *qrButton;
@property (nonatomic, strong) TLScannerButton *coverButton;
@property (nonatomic, strong) TLScannerButton *streetButton;
@property (nonatomic, strong) TLScannerButton *translateButton;
@end
@implementation TLScanningViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:self.scanVC.view];
[self addChildViewController:self.scanVC];
[self.view addSubview:self.bottomView];
[self.view addSubview:self.myQRButton];
[self.bottomView addSubview:self.qrButton];
[self.bottomView addSubview:self.coverButton];
[self.bottomView addSubview:self.streetButton];
[self.bottomView addSubview:self.translateButton];
[self p_addMasonry];
}
- (void)setDisableFunctionBar:(BOOL)disableFunctionBar
{
_disableFunctionBar = disableFunctionBar;
[self.bottomView setHidden:disableFunctionBar];
}
#pragma mark - TLScannerDelegate -
- (void)scannerViewControllerInitSuccess:(TLScannerViewController *)scannerVC
{
[self scannerButtonDown:self.qrButton]; // 初始化
}
- (void)scannerViewController:(TLScannerViewController *)scannerVC initFailed:(NSString *)errorString
{
[TLUIUtility showAlertWithTitle:@"错误" message:errorString cancelButtonTitle:@"确定" otherButtonTitles:nil actionHandler:^(NSInteger buttonIndex) {
[self.navigationController popViewControllerAnimated:YES];
}];
}
- (void)scannerViewController:(TLScannerViewController *)scannerVC scanAnswer:(NSString *)ansStr
{
[self p_analysisQRAnswer:ansStr];
}
#pragma mark - Event Response -
- (void)scannerButtonDown:(TLScannerButton *)sender
{
if (sender.isSelected) {
if (![self.scanVC isRunning]) {
[self.scanVC startCodeReading];
}
return;
}
self.curType = sender.type;
[self.qrButton setSelected:self.qrButton.type == sender.type];
[self.coverButton setSelected:self.coverButton.type == sender.type];
[self.streetButton setSelected:self.streetButton.type == sender.type];
[self.translateButton setSelected:self.translateButton.type == sender.type];
if (sender.type == TLScannerTypeQR) {
[self.navigationItem setRightBarButtonItem:self.albumBarButton];
[self.myQRButton setHidden:NO];
[self.navigationItem setTitle:LOCSTR(@"二维码/条码")];
}
else {
[self.navigationItem setRightBarButtonItem:nil];
[self.myQRButton setHidden:YES];
if (sender.type == TLScannerTypeCover) {
[self.navigationItem setTitle:LOCSTR(@"封面")];
}
else if (sender.type == TLScannerTypeStreet) {
[self.navigationItem setTitle:LOCSTR(@"街景")];
}
else if (sender.type == TLScannerTypeTranslate) {
[self.navigationItem setTitle:LOCSTR(@"翻译")];
}
}
[self.scanVC setScannerType:sender.type];
}
- (void)albumBarButtonDown:(UIBarButtonItem *)sender
{
[self.scanVC stopCodeReading];
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
[imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:imagePickerController animated:YES completion:nil];
[imagePickerController.rac_imageSelectedSignal subscribeNext:^(id x) {
[imagePickerController dismissViewControllerAnimated:YES completion:^{
UIImage *image = [x objectForKey:UIImagePickerControllerOriginalImage];
[TLUIUtility showLoading:@"扫描中,请稍候"];
[TLScannerViewController scannerQRCodeFromImage:image ans:^(NSString *ansStr) {
[TLUIUtility hiddenLoading];
if (ansStr == nil) {
[TLUIUtility showAlertWithTitle:@"扫描失败" message:@"请换张图片,或换个设备重试~" cancelButtonTitle:@"确定" otherButtonTitles:nil actionHandler:^(NSInteger buttonIndex) {
[self.scanVC startCodeReading];
}];
}
else {
[self p_analysisQRAnswer:ansStr];
}
}];
}];
} completed:^{
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
}];
}
- (void)myQRButtonDown
{
TLMyQRCodeViewController *myQRCodeVC = [[TLMyQRCodeViewController alloc] init];
PushVC(myQRCodeVC);
}
#pragma mark - Private Methods -
- (void)p_analysisQRAnswer:(NSString *)ansStr
{
if ([ansStr hasPrefix:@"http"]) {
TLWebViewController *webVC = [[TLWebViewController alloc] init];
[webVC setUrl:ansStr];
__block id vc = self.navigationController.rootViewController;
[self.navigationController popViewControllerAnimated:NO];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[webVC setHidesBottomBarWhenPushed:YES];
[[vc navigationController] pushViewController:webVC animated:YES];
});
}
else {
[TLUIUtility showAlertWithTitle:@"扫描结果" message:ansStr cancelButtonTitle:@"确定" otherButtonTitles:nil actionHandler:^(NSInteger buttonIndex) {
[self.scanVC startCodeReading];
}];
}
}
- (void)p_addMasonry
{
[self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.and.bottom.mas_equalTo(self.view);
make.height.mas_equalTo(HEIGHT_BOTTOM_VIEW);
}];
// bottom
CGFloat widthButton = 35;
CGFloat hightButton = 55;
CGFloat space = (SCREEN_WIDTH - widthButton * 4) / 5;
[self.qrButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.bottomView);
make.left.mas_equalTo(self.bottomView).mas_offset(space);
make.width.mas_equalTo(widthButton);
make.height.mas_equalTo(hightButton);
}];
[self.coverButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.bottom.and.width.mas_equalTo(self.qrButton);
make.left.mas_equalTo(self.qrButton.mas_right).mas_offset(space);
}];
[self.streetButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.bottom.and.width.mas_equalTo(self.qrButton);
make.left.mas_equalTo(self.coverButton.mas_right).mas_offset(space);
}];
[self.translateButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.bottom.and.width.mas_equalTo(self.qrButton);
make.left.mas_equalTo(self.streetButton.mas_right).mas_offset(space);
}];
[self.myQRButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.bottom.mas_equalTo(self.bottomView.mas_top).mas_offset(-40);
}];
}
#pragma mark - Getter -
- (TLScannerViewController *)scanVC
{
if (_scanVC == nil) {
_scanVC = [[TLScannerViewController alloc] init];
[_scanVC setDelegate:self];
}
return _scanVC;
}
- (UIView *)bottomView
{
if (_bottomView == nil) {
UIView *blackView = [[UIView alloc] init];
[blackView setBackgroundColor:[UIColor blackColor]];
[blackView setAlpha:0.5f];
_bottomView = [[UIView alloc] init];
[_bottomView addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(_bottomView);
}];
}
return _bottomView;
}
- (TLScannerButton *)qrButton
{
if (_qrButton == nil) {
_qrButton = [[TLScannerButton alloc] initWithType:TLScannerTypeQR title:@"扫码" iconPath:@"scan_QR" iconHLPath:@"scan_QR_HL"];
[_qrButton addTarget:self action:@selector(scannerButtonDown:) forControlEvents:UIControlEventTouchUpInside];
}
return _qrButton;
}
- (TLScannerButton *)coverButton
{
if (_coverButton == nil) {
_coverButton = [[TLScannerButton alloc] initWithType:TLScannerTypeCover title:@"封面" iconPath:@"scan_book" iconHLPath:@"scan_book_HL"];
[_coverButton addTarget:self action:@selector(scannerButtonDown:) forControlEvents:UIControlEventTouchUpInside];
}
return _coverButton;
}
- (TLScannerButton *)streetButton
{
if (_streetButton == nil) {
_streetButton = [[TLScannerButton alloc] initWithType:TLScannerTypeStreet title:@"街景" iconPath:@"scan_street" iconHLPath:@"scan_street_HL"];
[_streetButton addTarget:self action:@selector(scannerButtonDown:) forControlEvents:UIControlEventTouchUpInside];
}
return _streetButton;
}
- (TLScannerButton *)translateButton
{
if (_translateButton == nil) {
_translateButton = [[TLScannerButton alloc] initWithType:TLScannerTypeTranslate title:@"翻译" iconPath:@"scan_word" iconHLPath:@"scan_word_HL"];
[_translateButton addTarget:self action:@selector(scannerButtonDown:) forControlEvents:UIControlEventTouchUpInside];
}
return _translateButton;
}
- (UIBarButtonItem *)albumBarButton
{
if (_albumBarButton == nil) {
_albumBarButton = [[UIBarButtonItem alloc] initWithTitle:@"相册" style:UIBarButtonItemStylePlain target:self action:@selector(albumBarButtonDown:)];
}
return _albumBarButton;
}
- (UIButton *)myQRButton
{
if (_myQRButton == nil) {
_myQRButton = [[UIButton alloc] init];
[_myQRButton setTitle:LOCSTR(@"我的二维码") forState:UIControlStateNormal];
[_myQRButton.titleLabel setFont:[UIFont systemFontOfSize:15.0f]];
[_myQRButton setTitleColor:[UIColor colorGreenDefault] forState:UIControlStateNormal];
[_myQRButton addTarget:self action:@selector(myQRButtonDown) forControlEvents:UIControlEventTouchUpInside];
[_myQRButton setHidden:YES];
}
return _myQRButton;
}
@end
@@ -0,0 +1,15 @@
//
// TLScannerBackgroundView.h
// TLChat
//
// Created by 李伯坤 on 16/3/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TLScannerBackgroundView : UIView
- (void)addMasonryWithContainView:(UIView *)containView;
@end
@@ -0,0 +1,96 @@
//
// TLScannerBackgroundView.m
// TLChat
//
// Created by 李伯坤 on 16/3/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLScannerBackgroundView.h"
@interface TLScannerBackgroundView ()
@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UIView *btmView;
@property (nonatomic, strong) UIView *leftView;
@property (nonatomic, strong) UIView *rightView;
@end
@implementation TLScannerBackgroundView
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self addSubview:self.topView];
[self addSubview:self.btmView];
[self addSubview:self.leftView];
[self addSubview:self.rightView];
}
return self;
}
#pragma mark - Public Methods -
- (void)addMasonryWithContainView:(UIView *)containView
{
UIView *scannerView = containView;
[self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.left.and.right.mas_equalTo(self);
make.bottom.mas_equalTo(scannerView.mas_top);
}];
[self.btmView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.and.bottom.mas_equalTo(self);
make.top.mas_equalTo(scannerView.mas_bottom);
}];
[self.leftView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self);
make.right.mas_equalTo(scannerView.mas_left);
make.top.mas_equalTo(self.topView.mas_bottom);
make.bottom.mas_equalTo(self.btmView.mas_top);
}];
[self.rightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(scannerView.mas_right);
make.right.mas_equalTo(self);
make.top.mas_equalTo(self.topView.mas_bottom);
make.bottom.mas_equalTo(self.btmView.mas_top);
}];
}
#pragma mark - Getter -
- (UIView *)topView
{
if (_topView == nil) {
_topView = [[UIView alloc] init];
[_topView setBackgroundColor:[UIColor colorBlackAlphaScannerBG]];
}
return _topView;
}
- (UIView *)btmView
{
if (_btmView == nil) {
_btmView = [[UIView alloc] init];
[_btmView setBackgroundColor:[UIColor colorBlackAlphaScannerBG]];
}
return _btmView;
}
- (UIView *)leftView
{
if (_leftView == nil) {
_leftView = [[UIView alloc] init];
[_leftView setBackgroundColor:[UIColor colorBlackAlphaScannerBG]];
}
return _leftView;
}
- (UIView *)rightView
{
if (_rightView == nil) {
_rightView = [[UIView alloc] init];
[_rightView setBackgroundColor:[UIColor colorBlackAlphaScannerBG]];
}
return _rightView;
}
@end
@@ -0,0 +1,33 @@
//
// TLScannerButton.h
// TLChat
//
// Created by 李伯坤 on 16/2/25.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, TLScannerType) {
TLScannerTypeQR = 1, // 扫一扫 - 二维码
TLScannerTypeCover, // 扫一扫 - 封面
TLScannerTypeStreet, // 扫一扫 - 街景
TLScannerTypeTranslate, // 扫一扫 - 翻译
};
@interface TLScannerButton : UIButton
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *iconPath;
@property (nonatomic, strong) NSString *iconHLPath;
@property (nonatomic, assign) TLScannerType type;
@property (nonatomic, assign) NSUInteger msgNumber;
- (id)initWithType:(TLScannerType)type title:(NSString *)title iconPath:(NSString *)iconPath iconHLPath:(NSString *)iconHLPath;
@end
@@ -0,0 +1,94 @@
//
// TLScannerButton.m
// TLChat
//
// Created by 李伯坤 on 16/2/25.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLScannerButton.h"
@interface TLScannerButton ()
@property (nonatomic, strong) UIImageView *iconImageView;
@property (nonatomic, strong) UILabel *textLabel;
@end
@implementation TLScannerButton
- (id)initWithType:(TLScannerType)type title:(NSString *)title iconPath:(NSString *)iconPath iconHLPath:(NSString *)iconHLPath
{
if (self = [super init]) {
[self addSubview:self.iconImageView];
[self addSubview:self.textLabel];
[self p_addMasonry];
self.type = type;
self.title = title;
self.iconPath = iconPath;
self.iconHLPath = iconHLPath;
}
return self;
}
- (void)setTitle:(NSString *)title
{
_title = title;
[self.textLabel setText:title];
}
- (void)setIconPath:(NSString *)iconPath
{
_iconPath = iconPath;
[self.iconImageView setImage:[UIImage imageNamed:iconPath]];
}
- (void)setIconHLPath:(NSString *)iconHLPath
{
_iconHLPath = iconHLPath;
[self.iconImageView setHighlightedImage:[UIImage imageNamed:iconHLPath]];
}
- (void)setSelected:(BOOL)selected
{
[super setSelected:selected];
[self.iconImageView setHighlighted:selected];
[self.textLabel setHighlighted:selected];
}
#pragma mark - Private Methods -
- (void)p_addMasonry
{
[self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.left.and.right.mas_equalTo(self);
make.height.mas_equalTo(self.iconImageView.mas_width);
}];
[self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.mas_equalTo(self);
make.bottom.mas_equalTo(self);
}];
}
#pragma mark - Getter -
- (UIImageView *)iconImageView
{
if (_iconImageView == nil) {
_iconImageView = [[UIImageView alloc] init];
}
return _iconImageView;
}
- (UILabel *)textLabel
{
if (_textLabel == nil) {
_textLabel = [[UILabel alloc] init];
[_textLabel setFont:[UIFont systemFontOfSize:12.0f]];
[_textLabel setTextAlignment:NSTextAlignmentCenter];
[_textLabel setTextColor:[UIColor whiteColor]];
[_textLabel setHighlightedTextColor:[UIColor colorGreenDefault]];
}
return _textLabel;
}
@end
@@ -0,0 +1,22 @@
//
// TLScannerView.h
// TLChat
//
// Created by 李伯坤 on 16/3/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TLScannerView : UIView
/**
* 隐藏扫描指示器,默认NO
*/
@property (nonatomic, assign) BOOL hiddenScannerIndicator;
- (void)startScanner;
- (void)stopScanner;
@end
@@ -0,0 +1,174 @@
//
// TLScannerView.m
// TLChat
//
// Created by 李伯坤 on 16/3/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLScannerView.h"
@interface TLScannerView ()
{
NSTimer *timer;
}
@property (nonatomic, strong) UIView *bgView;
@property (nonatomic, strong) UIImageView *topLeftView;
@property (nonatomic, strong) UIImageView *topRightView;
@property (nonatomic, strong) UIImageView *btmLeftView;
@property (nonatomic, strong) UIImageView *btmRightView;
@property (nonatomic, strong) UIImageView *scannerLine;
@end
@implementation TLScannerView
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setClipsToBounds:YES];
[self addSubview:self.bgView];
[self addSubview:self.topLeftView];
[self addSubview:self.topRightView];
[self addSubview:self.btmLeftView];
[self addSubview:self.btmRightView];
[self addSubview:self.scannerLine];
[self p_addMasonry];
}
return self;
}
#pragma mark - Public Methods -
- (void)startScanner
{
[self stopScanner];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 60 block:^(NSTimer *timer) {
if (self.hiddenScannerIndicator) {
return;
}
self.scannerLine.centerX = self.bgView.centerX;
self.scannerLine.width = self.bgView.width * 1.4;
self.scannerLine.height = 10;
if (self.scannerLine.y + self.scannerLine.height >= self.height) {
self.scannerLine.y = 0;
}
else {
self.scannerLine.y ++;
}
} repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)stopScanner
{
if (timer) {
[timer invalidate];
timer = nil;
}
}
- (void)setHiddenScannerIndicator:(BOOL)hiddenScannerIndicator
{
if (hiddenScannerIndicator == _hiddenScannerIndicator) {
return;
}
if (hiddenScannerIndicator) {
self.scannerLine.y = 0;
[self.scannerLine setHidden:YES];
_hiddenScannerIndicator = hiddenScannerIndicator;
}
else {
_hiddenScannerIndicator = hiddenScannerIndicator;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.scannerLine.y = 0;
[self.scannerLine setHidden:hiddenScannerIndicator];
});
}
}
#pragma mark - Private Methods -
- (void)p_addMasonry
{
[_bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
[_topLeftView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.top.mas_equalTo(self);
make.width.and.height.mas_lessThanOrEqualTo(self);
}];
[_topRightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.and.top.mas_equalTo(self);
make.width.and.height.mas_lessThanOrEqualTo(self);
}];
[_btmLeftView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.bottom.mas_equalTo(self);
make.width.and.height.mas_lessThanOrEqualTo(self);
}];
[_btmRightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.and.bottom.mas_equalTo(self);
make.width.and.height.mas_lessThanOrEqualTo(self);
}];
}
#pragma mark - Getter -
- (UIView *)bgView
{
if (_bgView == nil) {
_bgView = [[UIView alloc] init];
[_bgView setBackgroundColor:[UIColor clearColor]];
[_bgView.layer setMasksToBounds:YES];
[_bgView.layer setBorderWidth:BORDER_WIDTH_1PX];
[_bgView.layer setBorderColor:[UIColor whiteColor].CGColor];
}
return _bgView;
}
- (UIImageView *)topLeftView
{
if (_topLeftView == nil) {
_topLeftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanner_top_left"]];
}
return _topLeftView;
}
- (UIImageView *)topRightView
{
if (_topRightView == nil) {
_topRightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanner_top_right"]];
}
return _topRightView;
}
- (UIImageView *)btmLeftView
{
if (_btmLeftView == nil) {
_btmLeftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanner_bottom_left"]];
}
return _btmLeftView;
}
- (UIImageView *)btmRightView
{
if (_btmRightView == nil) {
_btmRightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanner_bottom_right"]];
}
return _btmRightView;
}
- (UIImageView *)scannerLine
{
if (_scannerLine == nil) {
_scannerLine = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanner_line"]];
[_scannerLine setFrame:CGRectZero];
}
return _scannerLine;
}
@end