2013-11-20 3 views
1

나는 UIActivityIndicator 위치에 있습니다. 로딩 화면이있는 내 정보 페이지로 즉시 이동하지 마십시오.) CaptureOutput에 표시기를 표시하려고 시도했지만 [loadView setHidden:NO]은 무시됩니다. 왜 이런 일이 일어나는 걸까요? 그리고 검사가 끝난 직후에 바로 긋을 방법이 있습니까?AVCaptureDevice를 사용하여 바코드를 읽는 즉시 애니메이션 ActivityIndicator를 표시하려고합니다.

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 세션의 metadataObjectsCallbackQueue이 (그것을 실행하도록 설정되어 또는 1) 메인 큐로 설정되어 있지 않으면

#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 

답변

1

을 메인 스레드에서 [loadView setHidden : NO]를 호출하지 않습니다. (이것은 아마도 자기 performSegueWithIdentifier : @ "showInfo"sender : self]가 귀하의 정보 페이지로 바로 연결되지 않는 이유이기도합니다). UIKit의 대부분은 스레드로부터 안전하지 않으므로 "undefined"동작이 발생합니다.이 경우에는 아무것도 변경하지 않거나 지연 후에 만 ​​동작합니다.

나의 제안이 내 문제를 해결하기 때문에

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

일에 모든 UI 업데이트를 포장하는 것입니다. 거의 즉각적으로 실행되기 때문에 나는 활동 지표를 없앨 수 있습니다. – Mike