2014-11-22 52 views
1

我有一個應用程序,允許您掃描元數據的QR碼。根視圖控制器有兩個文本字段,並允許您使用掃描儀填充其中一個字段。訪問掃描儀的按鈕使用「顯示」segue將掃描視圖推入導航堆棧。無法在XCode 6中使用「顯示」segue「彈出」視圖控制器

我的意圖是,一旦有效掃描完成後,視圖控制器將數據傳回父控制器,然後將其刪除。

由於該視圖已被推送,我應該能夠實現popViewControllerAnimated,但這是行不通的。我也嘗試遍歷導航堆棧中的視圖控制器,匹配我試圖彈出的類並使用popToViewController,但仍然堅持我試圖從堆棧彈出的視圖。

我viewcontroller.m

@interface ScanQRViewController() 

@end 

@implementation ScanQRViewController 
@synthesize scanPreview, scanPreviewLayer, scanSession, addyString, delegate; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    scanSession = nil; 
    [self startScanning]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

#pragma mark QR code scanning 

-(void)startScanning { 
    addyString = nil; 
    NSError *error; 

    // create capture device and input 
    AVCaptureDevice *capDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:capDevice error:&error]; 

    // error checking 
    if(!input) { 
     NSLog(@"%@", [error localizedDescription]); 
    } 

    // init the capture session 
    scanSession = [[AVCaptureSession alloc] init]; 
    [scanSession addInput:input]; 
    AVCaptureMetadataOutput *metaOutput = [[AVCaptureMetadataOutput alloc] init]; 
    [scanSession addOutput:metaOutput]; 

    // assign to dispatch queue 
    dispatch_queue_t dispatchQueue; 
    dispatchQueue = dispatch_queue_create("qrQueue", NULL); 
    [metaOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; 
    [metaOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; 

    // create camera view for user 
    scanPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:scanSession]; 
    [scanPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 
    [scanPreviewLayer setFrame:scanPreview.layer.bounds]; 
    [scanPreview.layer addSublayer:scanPreviewLayer]; 

    // start running sesssion 
    [scanSession startRunning]; 
} 

- (void)stopScanning { 
    [scanSession stopRunning]; 
    scanSession = nil; 

    [scanPreviewLayer removeFromSuperlayer]; 
} 

#pragma mark AV Delegate Methods 

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { 

    // check for objects 
    if (metadataObjects != nil && [metadataObjects count] > 0) { 

     //get the last object 
     AVMetadataMachineReadableCodeObject *metaObj = [metadataObjects objectAtIndex:0]; 
     if([[metaObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { 

      // remove url string if exists 
      if ([[[metaObj stringValue] substringToIndex:9] isEqualToString:@"zetacoin:"]) { 
       addyString = [[metaObj stringValue] substringFromIndex:9]; 
      } else { 
       addyString = [metaObj stringValue]; 
      } 
     } 
     [self stopScanning]; 
     [self dismissView]; 
    } 
} 


#pragma mark - Navigation 

- (void)dismissView { 

    [delegate ScanQRCodeDidFinish:self]; 
    [self.navigationController popViewControllerAnimated:YES]; 

} 

@end 

回答

2

所以我想通了這個問題這個問題。本質上,當將數據傳回父控制器給委託時,我不在主線程中。因此它最終會暫停並返回到視圖,但速度很慢。我的兩個觀點:

QRScanner.m <掃描視圖

@interface ScanQRViewController() 

@end 

@implementation ScanQRViewController 
@synthesize scanPreview, scanPreviewLayer, scanSession, addyString, delegate; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    scanSession = nil; 
    [self startScanning]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

#pragma mark QR code scanning 

-(void)startScanning { 
    addyString = nil; 
    NSError *error; 

    // create capture device and input 
    AVCaptureDevice *capDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:capDevice error:&error]; 

    // error checking 
    if(!input) { 
     NSLog(@"%@", [error localizedDescription]); 
    } 

    // init the capture session 
    scanSession = [[AVCaptureSession alloc] init]; 
    [scanSession addInput:input]; 
    AVCaptureMetadataOutput *metaOutput = [[AVCaptureMetadataOutput alloc] init]; 
    [scanSession addOutput:metaOutput]; 

    // assign to dispatch queue 
    dispatch_queue_t dispatchQueue; 
    dispatchQueue = dispatch_queue_create("qrQueue", NULL); 
    [metaOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; 
    [metaOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; 

    // create camera view for user 
    scanPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:scanSession]; 
    [scanPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 
    [scanPreviewLayer setFrame:scanPreview.layer.bounds]; 
    [scanPreview.layer addSublayer:scanPreviewLayer]; 

    // start running sesssion 
    [scanSession startRunning]; 
} 

- (void)stopScanning { 
    [scanSession stopRunning]; 
    scanSession = nil; 

    [scanPreviewLayer removeFromSuperlayer]; 
} 

#pragma mark AV Delegate Methods 

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { 

    // check for objects 
    if (metadataObjects != nil && [metadataObjects count] > 0) { 

     //get the last object 
     AVMetadataMachineReadableCodeObject *metaObj = [metadataObjects objectAtIndex:0]; 
     if([[metaObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { 

      // remove url string if exists 
      if ([[[metaObj stringValue] substringToIndex:9] isEqualToString:@"zetacoin:"]) { 
       addyString = [[metaObj stringValue] substringFromIndex:9]; 
      } else { 
       addyString = [metaObj stringValue]; 
      } 
     } 
     [self stopScanning]; 
     [self dismissView]; 
    } 
} 


#pragma mark - Navigation 

- (void)dismissView { 

    NSLog(@"%@", self.navigationController); 
    [delegate ScanQRCodeDidFinish:self]; 

} 

@end 

AddAddress.m <我試圖返回

#import "AddAddressViewController.h" 
#import "ScanQRViewController.h" 

@interface AddAddressViewController() 

@end 

@implementation AddAddressViewController 
@synthesize nameField, addressField, addressText; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    self.navigationController.navigationItem.backBarButtonItem.title = @"Back"; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)viewWillAppear:(BOOL)animated { 

    // check to see if there's an address (QR) add to text field 
    if (addressText != nil) { 
     addressField.text = addressText; 
     NSLog(@"Address: %@", addressText); // debugging 
    } 
} 

#pragma mark delegate methods 

- (void)ScanQRCodeDidFinish:(ScanQRViewController *)sqrvc { 
    if (![NSThread isMainThread]) { 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      addressField.text = sqrvc.addyString; 
      [self.navigationController popViewControllerAnimated:YES]; 
     }); 
    } else { 
     addressField.text = sqrvc.addyString; 
     [self.navigationController popViewControllerAnimated:YES]; 
    } 
} 


#pragma mark - Navigation 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    ScanQRViewController *sqvc = [segue destinationViewController]; 
    sqvc.delegate = self; 
} 


@end 

通過添加dispatch_sync(dispatch_get_main_queue的觀點()^{它在主線程上執行並按預期返回視圖。

相關問題