diff --git a/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/iOS/FormsCameraView.ios.cs b/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/iOS/FormsCameraView.ios.cs index 29b50cad4..9c0b369bb 100644 --- a/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/iOS/FormsCameraView.ios.cs +++ b/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/iOS/FormsCameraView.ios.cs @@ -26,6 +26,7 @@ public sealed class FormsCameraView : UIView, IAVCaptureFileOutputRecordingDeleg bool isAvailable; bool isDisposed; CameraFlashMode flashMode; + PhotoCaptureDelegate? photoCaptureDelegate; readonly float imgScale = 1f; public event EventHandler? Busy; @@ -198,25 +199,19 @@ public async Task TakePhoto() // iOS >= 10 if (photoOutput != null) { - var photoOutputConnection = photoOutput.ConnectionFromMediaType(AVMediaType.Video); - if (photoOutputConnection != null) - photoOutputConnection.VideoOrientation = previewLayer.Connection?.VideoOrientation ?? throw new NullReferenceException(); - - var photoSettings = AVCapturePhotoSettings.Create(); - photoSettings.FlashMode = GetFlashMode(); - photoSettings.IsHighResolutionPhotoEnabled = true; - - var photoCaptureDelegate = new PhotoCaptureDelegate + try { - OnFinishCapture = (data, error) => - { - FinishCapture?.Invoke(this, new Tuple(data, error)); - IsBusy = false; - }, - WillCapturePhotoAnimation = () => Animate(0.25, () => previewLayer.Opacity = 1) - }; + var photoOutputConnection = photoOutput.ConnectionFromMediaType(AVMediaType.Video); + if (photoOutputConnection != null) + photoOutputConnection.VideoOrientation = previewLayer.Connection?.VideoOrientation ?? throw new NullReferenceException(); - photoOutput.CapturePhoto(photoSettings, photoCaptureDelegate); + photoOutput.CapturePhoto(GetCapturePhotoSettings(), GetPhotoCaptureDelegate()); + } + catch (Exception) + { + FinishCapture?.Invoke(this, new Tuple(null, new NSError(new NSString("Failed to create image"), 0))); + IsBusy = false; + } return; } @@ -231,7 +226,7 @@ public async Task TakePhoto() } catch (Exception) { - FinishCapture?.Invoke(this, new Tuple(null, new NSError(new NSString("faled create image"), 0))); + FinishCapture?.Invoke(this, new Tuple(null, new NSError(new NSString("Failed to create image"), 0))); } finally { @@ -239,6 +234,31 @@ public async Task TakePhoto() } } + AVCapturePhotoSettings GetCapturePhotoSettings() + { + var photoSettings = AVCapturePhotoSettings.Create(); + photoSettings.FlashMode = GetFlashMode(); + photoSettings.IsHighResolutionPhotoEnabled = true; + return photoSettings; + } + + PhotoCaptureDelegate GetPhotoCaptureDelegate() + { + if (photoCaptureDelegate == null) + { + photoCaptureDelegate = new PhotoCaptureDelegate + { + OnFinishCapture = (data, error) => + { + FinishCapture?.Invoke(this, new Tuple(data, error)); + IsBusy = false; + }, + WillCapturePhotoAnimation = () => Animate(0.25, () => previewLayer.Opacity = 1) + }; + } + return photoCaptureDelegate; + } + AVCaptureFlashMode GetFlashMode() { switch (flashMode) @@ -564,6 +584,9 @@ void ClearCaptureSession() captureSession.RemoveInput(input); } + photoCaptureDelegate?.Dispose(); + photoCaptureDelegate = null; + input?.Dispose(); input = null;