iOS Monotouch UIImagePickerController mehrere Fotos / Videos von der Kamera

Wir haben ein seltsames Problem mit einem UIImagePickerController. In unserer Anwendung können Benutzer eine Reihe von Formularen ausfüllen und Bilder und Videos in diese Formulare einfügen.

Wir erlauben Benutzern, mehrere Fotos / Videos entweder von der Kamerarolle hinzuzufügen oder zum Zeitpunkt des Ausfüllens des Formulars zu erfassen.

Wir benutzen dazu den UIImagePickerController. Das Problem tritt auf, wenn 1 oder 2 Bilder / Videos mit der Kamera aufgenommen wurden.

Sobald 1 oder 2 Bilder / Videos aufgenommen werden, wenn der Kamerabildschirm ein drittes Mal neu aufgerufen wird, ist das Bild statisch und wird nicht aktualisiert. Die Ansicht bleibt bei dem letzten Bild der zuletzt aufgenommenen Bilder hängen.

Wenn die Aufnahmetaste gedrückt wird, wird das Bild / Video plötzlich aktualisiert und hat erfasst, auf was die Kamera zeigte. Von da an ist der Picker gut dafür, dass sich ein anderer normal verhält. Wenn Sie zusätzlich ein Bild / Video aus der Kamerarolle auswählen, wird angezeigt, dass sich alles für ein anderes Bild / Video erneut verhält. Wenn der Bildschirm nicht reagiert und der Benutzer ein Bild aufgenommen hat, wird die Ansicht auf ein kleines Rechteck in der Ansicht verkleinert. Der Controller wird wie folgt eingerichtet:

    private void SourceChosen(EventHandler<UIImagePickerMediaPickedEventArgs> captureEvent, int buttonIndex, string[] mediaTypes)
    {
        var picker = ConfigurePicker(mediaTypes, captureEvent);

        if (CameraAvailable && buttonIndex == 0)
        {
            picker.SourceType = UIImagePickerControllerSourceType.Camera;
            picker.CameraDevice = UIImagePickerControllerCameraDevice.Rear;
            this.NavigationController.PresentViewController(picker, true, () => { });
        }

        if ((!CameraAvailable && buttonIndex == 0) || (CameraAvailable && buttonIndex == 1))
        {
            picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            this.NavigationController.PresentViewController(picker, false, () => { });
        }
    }

    private UIImagePickerController ConfigurePicker(string[] mediaTypes, EventHandler<UIImagePickerMediaPickedEventArgs> captureEvent)
    {
        var mediaPicker = new UIImagePickerController();
        mediaPicker.FinishedPickingMedia += captureEvent;
        mediaPicker.Canceled += (sender, args) => mediaPicker.DismissViewController(true, () => { });
        mediaPicker.SetBarDefaults();
        mediaPicker.MediaTypes = mediaTypes;
        return mediaPicker;
    }

Ein Beispiel für ein captureEvent lautet wie folgt:

    void PhotoChosen(object sender, UIImagePickerMediaPickedEventArgs e)
    {
        UIImage item = e.OriginalImage;
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "png");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        NSData imageData = item.AsPNG();
        CopyData(imageData, path, fileName, ViewModel.Images, ((UIImagePickerController)sender));
    }

    private void CopyData(NSData imageData, string path, string fileName, List<AssociatedItem> collectionToAddTo, UIImagePickerController picker)
    {
        byte[] imageBytes = new byte[imageData.Length];
        System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, imageBytes, 0, Convert.ToInt32(imageData.Length));
        File.WriteAllBytes(path, imageBytes);

        AssociatedItem item = new AssociatedItem
        {
            StorageKey = fileName
        };

        collectionToAddTo.Add(item);
        picker.DismissViewController(true, ReloadTables);
    }

Wie Sie sehen, haben wir im Moment keinen Verweis auf den Picker, aber wir haben versucht, Variationen dieses Codes zu erstellen, in denen wir einen Verweis auf den Picker speichern und nach der CopyData-Methode ablegen. Wir haben picker.Release () hinzugefügt. ; Nach den Kopierdaten und vor dem Entsorgen (führt dazu, dass nachfolgende Picker die Anwendung zum Absturz bringen, wenn sie angezeigt werden) und so ziemlich jede andere Variation des Themas.

Hat jemand eine Ahnung, warum dies auftreten könnte und wie es behoben werden kann? Ich bin davon ausgegangen, dass der Speicher knapp wird, wir aber nicht jedes Mal eine Instanz erstellen und den Modus von Bildern zu Videos ändern. Dies hat keinerlei Auswirkungen und wir sehen immer dasselbe Verhalten.

BEARBEITEN

Dank Kento und der folgenden Antwort war etwas in der Art von:

public class PickerDelegate : UIImagePickerControllerDelegate
{
    private readonly Action<UIImagePickerController, NSDictionary> _captureEvent;

    public PickerDelegate(Action<UIImagePickerController, NSDictionary> captureEvent)
    {
        _captureEvent = captureEvent;
    }

    public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info)
    {
        _captureEvent(picker, info);
    }
}

Dann um ein Bild zu bekommen

    void PhotoChosen(UIImagePickerController picker, NSDictionary info)
    {
        UIImage item = (UIImage)info.ObjectForKey(UIImagePickerController.OriginalImage);
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "png");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        NSData imageData = item.AsPNG();
        CopyData(imageData, path, fileName, ViewModel.Images, picker);
    }

Oder um ein Video zu bekommen

    void VideoChosen(UIImagePickerController picker, NSDictionary info)
    {
        var videoURL = (NSUrl)info.ObjectForKey(UIImagePickerController.MediaURL);
        NSData videoData = NSData.FromUrl(videoURL);
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "mov");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        CopyData(videoData, path, fileName, ViewModel.Videos, picker);
    }

Antworten auf die Frage(2)

Ihre Antwort auf die Frage