mirror of
https://github.com/simplezhli/flutter_barcode_reader.git
synced 2024-11-22 21:59:23 +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:
|
||||
- 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:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
@ -17,7 +17,7 @@ EXTERNAL SOURCES:
|
||||
barcode_scan:
|
||||
:path: "/Users/dustin/Documents/workspace_flutter/flutter_barcode_reader/ios"
|
||||
Flutter:
|
||||
:path: "/Users/dustin/flutter/bin/cache/artifacts/engine/ios-release"
|
||||
:path: "/Users/dustin/flutter/bin/cache/artifacts/engine/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
barcode_scan: 8288e70cb430072003bce2c794a1431e7adbcb4d
|
||||
|
@ -273,7 +273,7 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${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";
|
||||
outputPaths = (
|
||||
|
@ -1,6 +1,11 @@
|
||||
#import <Flutter/Flutter.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>
|
||||
|
||||
|
@ -6,11 +6,15 @@
|
||||
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
||||
|
||||
#import "BarcodeScannerViewControllerDelegate.h"
|
||||
#import "ScannerOverlay.h"
|
||||
|
||||
|
||||
@interface BarcodeScannerViewController : UIViewController
|
||||
@property(nonatomic, retain) UIView *previewView;
|
||||
@property(nonatomic, retain) ScannerOverlay *scanRect;
|
||||
@property(nonatomic, retain) MTBBarcodeScanner *scanner;
|
||||
@property(nonatomic, weak) id<BarcodeScannerViewControllerDelegate> delegate;
|
||||
|
||||
|
||||
-(id) initWithOptions:(NSDictionary *) options;
|
||||
@end
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#import "BarcodeScannerViewController.h"
|
||||
#import <MTBBarcodeScanner/MTBBarcodeScanner.h>
|
||||
#import "ScannerOverlay.h"
|
||||
|
||||
|
||||
@implementation BarcodeScannerViewController {
|
||||
@ -25,7 +26,26 @@
|
||||
options:NSLayoutFormatAlignAllBottom
|
||||
metrics:nil
|
||||
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];
|
||||
__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 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