make iOS scanner UI look the same as Android

Includes a scanner window and pulsing scan line
This commit is contained in:
dustin 2018-08-11 09:17:35 -07:00
parent 6de69d7c2a
commit 1074ab990a
7 changed files with 141 additions and 3 deletions

View File

@ -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

View File

@ -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 = (

View File

@ -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>

View File

@ -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

View File

@ -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];
}

View File

@ -0,0 +1,8 @@
#import <UIKit/UIKit.h>
@interface ScannerOverlay : UIView
@property(nonatomic) CGRect scanLineRect;
- (void) startAnimating;
- (void) stopAnimating;
@end

View 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