iOS Monotouch UIImagePickerController来自相机的多张照片/video

我们遇到了一个UIImagePickerController的奇怪问题。 在我们的应用程序中,用户可以填写一系列表格,还可以在这些表格中附加图像和video。

我们允许用户从相机胶卷添加多张照片/video,或者在填写表格时进行拍摄。

我们正在使用UIImagePickerController来执行此操作。 使用相机拍摄1或2张图像/video时会出现此问题。

在第三次重新进入相​​机屏幕时捕获1或2个图像/video时,图像是静态的,不会更新。 视图停留在最后捕获的任何内容的最后一帧。

如果按下捕获按钮,则图像/video会突然更新并捕获相机指向的内容。 从那时起,选择器对于另一个正常行为是好的。 此外,从相机胶卷中选择一张照片/video似乎可以使所有内容再次显示另一张照片/video。 最后,当屏幕没有响应并且用户选择拍照时,视图将缩小为视图内的小矩形。 控制器的设置如下:

private void SourceChosen(EventHandler 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 captureEvent) { var mediaPicker = new UIImagePickerController(); mediaPicker.FinishedPickingMedia += captureEvent; mediaPicker.Canceled += (sender, args) => mediaPicker.DismissViewController(true, () => { }); mediaPicker.SetBarDefaults(); mediaPicker.MediaTypes = mediaTypes; return mediaPicker; } 

captureEvent的示例如下:

  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 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); } 

目前您可以看到我们没有持有对选择器的引用,但是我们尝试了这个代码的变体,我们存储了对选择器的引用并在CopyData方法之后处理它,我们添加了picker.Release() ; 在copydata之后和处置之前(导致随后的选择器在显示时崩溃应用程序)以及主题上几乎所有其他变体。

有谁知道为什么会发生这种情况以及如何解决这个问题? 我的假设是我们可能在内存上运行不足,但每次都没有处理它/只创建一个实例并且从图片到video改变它的模式有任何影响,我们总是看到相同的行为。

编辑

感谢Kento以及下面的回答我们需要让所有工作按预期工作的内容如下:

 public class PickerDelegate : UIImagePickerControllerDelegate { private readonly Action _captureEvent; public PickerDelegate(Action captureEvent) { _captureEvent = captureEvent; } public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info) { _captureEvent(picker, info); } } 

然后得到一个图像

  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); } 

或者获取video

  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); } 

我有同样的问题。

这里的post没有标记为答案,但确实为我解决了这个问题: https : //stackoverflow.com/a/20035698/2514318

我猜这是使用FinishedPickingMedia事件时MonoTouch的错误。 我已经读过使用UIImagePickerController存在泄漏(无论使用obj c还是Mono),所以我更喜欢保留实例并重新使用它。 如果你每次都重新创建它,我会建议处理前一个实例。

如果这是一个错误,Xamarin的任何人都可以权衡吗?

这篇文章给了我很多帮助,所以我决定制作一个非常简单的样本并在github上发布给任何可能需要它的人: https : //github.com/GiusepeCasagrande/XamarinSimpleCameraSample