[英]Using AVCaptureDevice to read Barcodes, I want to show an animated ActivityIndicator immediately After the scan
I have the UIActivityIndicator
Place in the view, and I am try to get it to show after I scan the barcode (Because for some reason it won't immediately segue to my info page that has a loading screen on it.) I try to show the Indicator in CaptureOutput
but the [loadView setHidden:NO]
is just ignored. 我在视图中有UIActivityIndicator
Place,并且尝试在扫描条形码后显示它(由于某种原因,它不会立即显示在具有加载屏幕的信息页面上。)在CaptureOutput
显示指示器,但是[loadView setHidden:NO]
被忽略。 Why is this happening? 为什么会这样呢? And is there a way to just segue immediately after the scan? 有没有办法在扫描后立即进行搜索?
BRISBNScanner.h BRISBNScanner.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface BRISBNScanner : UIViewController <AVCaptureMetadataOutputObjectsDelegate>
{
IBOutlet UIActivityIndicatorView *loadView;
}
@property (strong, nonatomic) AVCaptureDevice* device;
@property (strong, nonatomic) AVCaptureDeviceInput* input;
@property (strong, nonatomic) AVCaptureMetadataOutput* output;
@property (strong, nonatomic) AVCaptureSession* session;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer* preview;
@property (strong, nonatomic) NSString *isbnText;
@end
BRISBNScanner.m BRISBNScanner.m
#import "BRISBNScanner.h"
#import "BRScanInfoView.h"
@interface BRISBNScanner ()
@end
@implementation BRISBNScanner
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Device
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// Input
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
// Output
self.output = [[AVCaptureMetadataOutput alloc] init];
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// Session
self.session = [[AVCaptureSession alloc] init];
[self.session addInput:self.input];
[self.session addOutput:self.output];
self.output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code];
// Preview
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.preview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.layer insertSublayer:self.preview atIndex:0];
// Start
[self.session startRunning];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
[loadView setHidden:NO];
[self.session stopRunning];
for(AVMetadataObject *metadataObject in metadataObjects)
{
AVMetadataMachineReadableCodeObject *readableObject = (AVMetadataMachineReadableCodeObject *)metadataObject;
if ([metadataObject.type isEqualToString:AVMetadataObjectTypeEAN13Code])
{
NSLog(@"EAN 13 = %@", readableObject.stringValue);
_isbnText = readableObject.stringValue;
[loadView setHidden:YES];
[self performSegueWithIdentifier:@"showInfo" sender:self];
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray: self.navigationController.viewControllers];
[viewControllers removeObjectIdenticalTo:self];
[self.navigationController setViewControllers: viewControllers animated: YES];
}
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showInfo"]) {
BRScanInfoView *scanView = (BRScanInfoView *)[segue destinationViewController];
//The view that uses the ISBN to search for stuff
scanView.isbnTextprop = _isbnText;
}
}
@end
Unless the session's metadataObjectsCallbackQueue is set to the main queue (or one that's set up to execute on it) you're not calling [loadView setHidden:NO] from the main thread. 除非会话的metadataObjectsCallbackQueue设置为主队列(或设置为在其上执行的队列),否则您不会从主线程调用[loadView setHidden:NO]。 (This is probably also why [self performSegueWithIdentifier:@"showInfo" sender:self] doesn't immediately segue to your info page). (这也可能就是[self performSegueWithIdentifier:@“ showInfo” sender:self]不立即隔离到您的信息页的原因)。 Since most of UIKit isn't thread safe this leads to "undefined" behaviour, in this case not changing anything or only after a delay respectively. 由于大多数UIKit都不是线程安全的,因此会导致“未定义”的行为,在这种情况下,不进行任何更改或仅在延迟之后才进行更改。
My suggestion would be to wrap all your ui-updates in a 我的建议是将所有ui更新都包装在
dispatch_async(dispatch_get_main_queue(), ^{
//ui-updates
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.