2016-10-21 9 views
1

私はログイン用のQRコードを読み、代わりにコードを入力してログインできる小さなアプリを持っています。 アプリが起動し、ログイン(表示)に直接進みます。私が動作しないqrコードをスキャンしようとすると、デリゲートは決して呼び出されません/イベントは発生しません。 iOS:カメラがビューコントローラの最初の読み込み時にQRコードを認識しない

私はラリー・オブライエン http://www.knowing.net/index.php/2013/10/09/natively-recognize-barcodesqr-codes-in-ios-7-with-xamarin-ios/

からのアプローチを適応し、その使用のために私自身のScannerViewクラスを作成しました:

public sealed partial class ScannerView : UIView 
{ 
    private readonly AVCaptureVideoPreviewLayer _layer; 
    public AVCaptureSession Session { get; } 
    private readonly AVCaptureMetadataOutput _metadataOutput; 

    public event EventHandler<AVMetadataMachineReadableCodeObject> MetadataFound = delegate { }; 
    public ScannerView (IntPtr handle) : base (handle) 
    { 
     Session = new AVCaptureSession(); 
     var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video); 
     var input = AVCaptureDeviceInput.FromDevice(camera); 
     Session.AddInput(input); 

     //Add the metadata output channel 
     _metadataOutput = new AVCaptureMetadataOutput {RectOfInterest = Bounds}; 
     var metadataDelegate = new MetadataOutputDelegate(); 
     var dispatchQueue = new DispatchQueue("scannerQueue"); 
     _metadataOutput.SetDelegate(metadataDelegate, dispatchQueue); 
     Session.AddOutput(_metadataOutput); 

     _layer = new AVCaptureVideoPreviewLayer(Session) 
     { 
      MasksToBounds = true, 
      VideoGravity = AVLayerVideoGravity.ResizeAspectFill, 
      Frame = Bounds 
     }; 

     Layer.AddSublayer(_layer); 

     // Hand event over to subscriber 
     metadataDelegate.MetadataFound += (s, e) => MetadataFound(s, e); 
    } 

    public override void LayoutSubviews() 
    { 
     base.LayoutSubviews(); 
     _layer.Frame = Bounds; 
     _metadataOutput.RectOfInterest = Bounds; 
    } 

    public void SetMetadataType(AVMetadataObjectType type) 
    { 
     //Confusing! *After* adding to session, tell output what to recognize... 
     _metadataOutput.MetadataObjectTypes = type; 
    } 
} 

そして、私のLoginViewに私は次の操作を行います。

public override void ViewWillAppear(bool animated) 
    { 
     base.ViewWillAppear(animated); 
     // Manipulate navigation stack 
     NavigationController.SetViewControllers(
      NavigationController.ViewControllers.Where(
       viewController => viewController is LoginView).ToArray(), false); 

     ScannerView.MetadataFound += (s, e) => 
     { 
      Console.WriteLine($"Found: [{e.Type.ToString()}] {e.StringValue}"); 
      LoginViewModel.BarCode = e.StringValue; 
      if (LoginViewModel.DoneCommand.CanExecute()) 
      { 
       ScannerView.Session.StopRunning(); 
       LoginViewModel.DoneCommand.Execute(); 
      } 
     }; 
    } 

    public override void ViewDidAppear(bool animated) 
    { 
     base.ViewDidAppear(animated); 
     ScannerView.Session.StartRunning(); 
     ScannerView.SetMetadataType(AVMetadataObjectType.QRCode | AVMetadataObjectType.EAN13Code); 
    } 

おかしいですこれは、手動入力でログインしてもう一度ログアウトすると動作しますので、私は再び同じ画面に表示されます(同じではないかもしれませんが、新しいinstそれは、GCがナビゲーションスタックから削除されるときにビューを破壊する可能性があります)。

私は、storyview内のLoginViewのサブビューとしてscannerviewを配置しました。ナビゲーションのためにMVVMCrossを使用します。 (ちょうど情報のため)

So:私は間違って何をしていますか?最初の負荷で動作させるためには何が必要ですか? (私は同じコードを使って、一度それを行うことができました...多分タイミング問題ですか?)

答えて

0

明らかにこれはタイミングの問題です。 "Tap to scan"パラダイムを追加して解決しました。 私は次のコードを実行し、タッピング:MetadataObjectTypeが我々の前に探しているコードに設定されている

 public override void TouchesBegan(NSSet touches, UIEvent evt) 
    { 
     base.TouchesBegan(touches, evt); 
     Console.WriteLine($"Current types to scan: {this.MetadataOutput.MetadataObjectTypes}"); 
     this.SetMetadataType(this.MetadataObjectType); 
     Console.WriteLine($"New types to scan: {this.MetadataOutput.MetadataObjectTypes}"); 
    } 

    public void SetMetadataType(AVMetadataObjectType type) 
    { 
     //Confusing! *After* adding to session, tell output what to recognize... 
     this.Session.BeginConfiguration(); 
     this.MetadataOutput.MetadataObjectTypes = type; 
     this.Session.CommitConfiguration(); 
    } 

を。 これで問題は解決します。スキャンは毎回動作します。 私は魔法の部分がBegin-とCommitConfigurationコールであると思います。これは、タッチを使ってパラダイムをスキャンしなければ、これも機能します。

関連する問題