gpt4 book ai didi

ios - 使用 AVCaptureDevice 读取条形码,我想在扫描后立即显示动画 ActivityIndi​​cator

转载 作者:行者123 更新时间:2023-11-29 12:59:44 25 4
gpt4 key购买 nike

我在 View 中放置了 UIActivityIndi​​cator,我试图在扫描条形码后显示它(因为出于某种原因,它不会立即转到我的信息页面上面有加载屏幕。)我尝试在 CaptureOutput 中显示 Indicator,但 [loadView setHidden:NO] 被忽略了。为什么会这样?有没有办法在扫描后立即进行 segue?

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

#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

最佳答案

除非 session 的 metadataObjectsCallbackQueue 设置为主队列(或设置为在其上执行的队列),否则您不会从主线程调用 [loadView setHidden:NO]。 (这可能也是为什么 [self performSegueWithIdentifier:@"showInfo"sender:self] 不会立即转到您的信息页面)。由于大多数 UIKit 不是线程安全的,这会导致“未定义”行为,在这种情况下,不会更改任何内容或仅在分别延迟后才更改。

我的建议是将所有 ui-updates 包装在一个

dispatch_async(dispatch_get_main_queue(), ^{
//ui-updates
});

关于ios - 使用 AVCaptureDevice 读取条形码,我想在扫描后立即显示动画 ActivityIndi​​cator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20107215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com