mirror of
https://github.com/simplezhli/flutter_barcode_reader.git
synced 2024-11-23 07:59:20 +08:00
make iOS scanner UI look the same as Android
Includes a scanner window and pulsing scan line
This commit is contained in:
parent
6de69d7c2a
commit
1074ab990a
@ -7,7 +7,7 @@ PODS:
|
|||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- barcode_scan (from `/Users/dustin/Documents/workspace_flutter/flutter_barcode_reader/ios`)
|
- barcode_scan (from `/Users/dustin/Documents/workspace_flutter/flutter_barcode_reader/ios`)
|
||||||
- Flutter (from `/Users/dustin/flutter/bin/cache/artifacts/engine/ios-release`)
|
- Flutter (from `/Users/dustin/flutter/bin/cache/artifacts/engine/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://github.com/cocoapods/specs.git:
|
https://github.com/cocoapods/specs.git:
|
||||||
@ -17,7 +17,7 @@ EXTERNAL SOURCES:
|
|||||||
barcode_scan:
|
barcode_scan:
|
||||||
:path: "/Users/dustin/Documents/workspace_flutter/flutter_barcode_reader/ios"
|
:path: "/Users/dustin/Documents/workspace_flutter/flutter_barcode_reader/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: "/Users/dustin/flutter/bin/cache/artifacts/engine/ios-release"
|
:path: "/Users/dustin/flutter/bin/cache/artifacts/engine/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
barcode_scan: 8288e70cb430072003bce2c794a1431e7adbcb4d
|
barcode_scan: 8288e70cb430072003bce2c794a1431e7adbcb4d
|
||||||
|
@ -273,7 +273,7 @@
|
|||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${PODS_ROOT}/../../../../../../flutter/bin/cache/artifacts/engine/ios-release/Flutter.framework",
|
"${PODS_ROOT}/../../../../../../flutter/bin/cache/artifacts/engine/ios/Flutter.framework",
|
||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#import <Flutter/Flutter.h>
|
#import <Flutter/Flutter.h>
|
||||||
#import "BarcodeScannerViewControllerDelegate.h"
|
#import "BarcodeScannerViewControllerDelegate.h"
|
||||||
|
|
||||||
|
#define UIColorFromRGB(rgbValue) \
|
||||||
|
[UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
|
||||||
|
green:((float)((rgbValue & 0x00FF00) >> 8))/255.0 \
|
||||||
|
blue:((float)((rgbValue & 0x0000FF) >> 0))/255.0 \
|
||||||
|
alpha:1.0]
|
||||||
|
|
||||||
@interface BarcodeScanPlugin : NSObject<FlutterPlugin, BarcodeScannerViewControllerDelegate>
|
@interface BarcodeScanPlugin : NSObject<FlutterPlugin, BarcodeScannerViewControllerDelegate>
|
||||||
|
|
||||||
|
@ -6,11 +6,15 @@
|
|||||||
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
||||||
|
|
||||||
#import "BarcodeScannerViewControllerDelegate.h"
|
#import "BarcodeScannerViewControllerDelegate.h"
|
||||||
|
#import "ScannerOverlay.h"
|
||||||
|
|
||||||
|
|
||||||
@interface BarcodeScannerViewController : UIViewController
|
@interface BarcodeScannerViewController : UIViewController
|
||||||
@property(nonatomic, retain) UIView *previewView;
|
@property(nonatomic, retain) UIView *previewView;
|
||||||
|
@property(nonatomic, retain) ScannerOverlay *scanRect;
|
||||||
@property(nonatomic, retain) MTBBarcodeScanner *scanner;
|
@property(nonatomic, retain) MTBBarcodeScanner *scanner;
|
||||||
@property(nonatomic, weak) id<BarcodeScannerViewControllerDelegate> delegate;
|
@property(nonatomic, weak) id<BarcodeScannerViewControllerDelegate> delegate;
|
||||||
|
|
||||||
|
|
||||||
|
-(id) initWithOptions:(NSDictionary *) options;
|
||||||
@end
|
@end
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#import "BarcodeScannerViewController.h"
|
#import "BarcodeScannerViewController.h"
|
||||||
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
||||||
|
#import "ScannerOverlay.h"
|
||||||
|
|
||||||
|
|
||||||
@implementation BarcodeScannerViewController {
|
@implementation BarcodeScannerViewController {
|
||||||
@ -25,7 +26,26 @@
|
|||||||
options:NSLayoutFormatAlignAllBottom
|
options:NSLayoutFormatAlignAllBottom
|
||||||
metrics:nil
|
metrics:nil
|
||||||
views:@{@"previewView": _previewView}]];
|
views:@{@"previewView": _previewView}]];
|
||||||
|
self.scanRect = [[ScannerOverlay alloc] initWithFrame:self.view.bounds];
|
||||||
|
self.scanRect.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
|
self.scanRect.backgroundColor = UIColor.clearColor;
|
||||||
|
[self.view addSubview:_scanRect];
|
||||||
|
[self.view addConstraints:[NSLayoutConstraint
|
||||||
|
constraintsWithVisualFormat:@"V:[scanRect]"
|
||||||
|
options:NSLayoutFormatAlignAllBottom
|
||||||
|
metrics:nil
|
||||||
|
views:@{@"scanRect": _scanRect}]];
|
||||||
|
[self.view addConstraints:[NSLayoutConstraint
|
||||||
|
constraintsWithVisualFormat:@"H:[scanRect]"
|
||||||
|
options:NSLayoutFormatAlignAllBottom
|
||||||
|
metrics:nil
|
||||||
|
views:@{@"scanRect": _scanRect}]];
|
||||||
|
[_scanRect startAnimating];
|
||||||
self.scanner = [[MTBBarcodeScanner alloc] initWithPreviewView:_previewView];
|
self.scanner = [[MTBBarcodeScanner alloc] initWithPreviewView:_previewView];
|
||||||
|
__weak BarcodeScannerViewController *weakSelf = self;
|
||||||
|
self.scanner.didStartScanningBlock = ^{
|
||||||
|
weakSelf.scanner.scanRect = weakSelf.scanRect.scanLineRect;
|
||||||
|
};
|
||||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)];
|
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)];
|
||||||
[self updateFlashButton];
|
[self updateFlashButton];
|
||||||
}
|
}
|
||||||
|
8
ios/Classes/ScannerOverlay.h
Normal file
8
ios/Classes/ScannerOverlay.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface ScannerOverlay : UIView
|
||||||
|
@property(nonatomic) CGRect scanLineRect;
|
||||||
|
|
||||||
|
- (void) startAnimating;
|
||||||
|
- (void) stopAnimating;
|
||||||
|
@end
|
101
ios/Classes/ScannerOverlay.m
Normal file
101
ios/Classes/ScannerOverlay.m
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#import "ScannerOverlay.h"
|
||||||
|
|
||||||
|
@interface ScannerOverlay()
|
||||||
|
@property(nonatomic, retain) UIView *line;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ScannerOverlay
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:frame];
|
||||||
|
if (self) {
|
||||||
|
_line = [[UIView alloc] init];
|
||||||
|
_line.backgroundColor = UIColor.redColor;
|
||||||
|
_line.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
|
[self addSubview:_line];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(CGRect)rect {
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
|
||||||
|
UIColor * overlayColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.55];
|
||||||
|
UIColor *scanLineColor = UIColor.redColor;
|
||||||
|
|
||||||
|
CGContextSetFillColorWithColor(context, overlayColor.CGColor);
|
||||||
|
CGContextFillRect(context, self.bounds);
|
||||||
|
|
||||||
|
// make a hole for the scanner
|
||||||
|
CGRect holeRect = [self scanRect];
|
||||||
|
CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );
|
||||||
|
[[UIColor clearColor] setFill];
|
||||||
|
UIRectFill(holeRectIntersection);
|
||||||
|
|
||||||
|
// draw a horizontal line over the middle
|
||||||
|
CGRect lineRect = [self scanLineRect];
|
||||||
|
_line.frame = lineRect;
|
||||||
|
|
||||||
|
// drw the green corners
|
||||||
|
CGFloat cornerSize = 30;
|
||||||
|
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||||
|
//top left corner
|
||||||
|
[path moveToPoint:CGPointMake(holeRect.origin.x, holeRect.origin.y + cornerSize)];
|
||||||
|
[path addLineToPoint:CGPointMake(holeRect.origin.x, holeRect.origin.y)];
|
||||||
|
[path addLineToPoint:CGPointMake(holeRect.origin.x + cornerSize, holeRect.origin.y)];
|
||||||
|
|
||||||
|
//top right corner
|
||||||
|
CGFloat rightHoleX = holeRect.origin.x + holeRect.size.width;
|
||||||
|
[path moveToPoint:CGPointMake(rightHoleX - cornerSize, holeRect.origin.y)];
|
||||||
|
[path addLineToPoint:CGPointMake(rightHoleX, holeRect.origin.y)];
|
||||||
|
[path addLineToPoint:CGPointMake(rightHoleX, holeRect.origin.y + cornerSize)];
|
||||||
|
|
||||||
|
// bottom right corner
|
||||||
|
CGFloat bottomHoleY = holeRect.origin.y + holeRect.size.height;
|
||||||
|
[path moveToPoint:CGPointMake(rightHoleX, bottomHoleY - cornerSize)];
|
||||||
|
[path addLineToPoint:CGPointMake(rightHoleX, bottomHoleY)];
|
||||||
|
[path addLineToPoint:CGPointMake(rightHoleX - cornerSize, bottomHoleY)];
|
||||||
|
|
||||||
|
// bottom left corner
|
||||||
|
[path moveToPoint:CGPointMake(holeRect.origin.x + cornerSize, bottomHoleY)];
|
||||||
|
[path addLineToPoint:CGPointMake(holeRect.origin.x, bottomHoleY)];
|
||||||
|
[path addLineToPoint:CGPointMake(holeRect.origin.x, bottomHoleY - cornerSize)];
|
||||||
|
|
||||||
|
path.lineWidth = 2;
|
||||||
|
[[UIColor greenColor] setStroke];
|
||||||
|
[path stroke];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startAnimating {
|
||||||
|
CABasicAnimation *flash = [CABasicAnimation animationWithKeyPath:@"opacity"];
|
||||||
|
flash.fromValue = [NSNumber numberWithFloat:0.0];
|
||||||
|
flash.toValue = [NSNumber numberWithFloat:1.0];
|
||||||
|
flash.duration = 0.25;
|
||||||
|
flash.autoreverses = YES;
|
||||||
|
flash.repeatCount = HUGE_VALF;
|
||||||
|
[_line.layer addAnimation:flash forKey:@"flashAnimation"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopAnimating {
|
||||||
|
[self.layer removeAnimationForKey:@"flashAnimation"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGRect)scanRect {
|
||||||
|
CGRect rect = self.frame;
|
||||||
|
CGFloat heightMultiplier = 3.0/4.0; // 4:3 aspect ratio
|
||||||
|
CGFloat scanRectWidth = rect.size.width * 0.8f;
|
||||||
|
CGFloat scanRectHeight = scanRectWidth * heightMultiplier;
|
||||||
|
CGFloat scanRectOriginX = (rect.size.width / 2) - (scanRectWidth / 2);
|
||||||
|
CGFloat scanRectOriginY = (rect.size.height / 2) - (scanRectHeight / 2);
|
||||||
|
return CGRectMake(scanRectOriginX, scanRectOriginY, scanRectWidth, scanRectHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGRect)scanLineRect {
|
||||||
|
CGRect scanRect = [self scanRect];
|
||||||
|
CGRect rect = self.frame;
|
||||||
|
return CGRectMake(scanRect.origin.x, rect.size.height / 2, scanRect.size.width, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue
Block a user