/// <summary>
        /// Views the did load.
        /// </summary>
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Hide no camera label
            NoCamera.Hidden = ThisApp.CameraAvailable;

            // Attach to camera view
            ThisApp.Recorder.DisplayView = CameraView;

            // Set min and max values
            Offset.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
            Offset.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;

            Duration.MinValue = 0.0f;
            Duration.MaxValue = 1.0f;

            ISO.MinValue = ThisApp.CaptureDevice.ActiveFormat.MinISO;
            ISO.MaxValue = ThisApp.CaptureDevice.ActiveFormat.MaxISO;

            Bias.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
            Bias.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;

            // Create a timer to monitor and update the UI
            SampleTimer          = new Timer(5000);
            SampleTimer.Elapsed += (sender, e) => {
                // Update position slider
                Offset.BeginInvokeOnMainThread(() => {
                    Offset.Value = ThisApp.Input.Device.ExposureTargetOffset;
                });

                Duration.BeginInvokeOnMainThread(() => {
                    var newDurationSeconds = CMTimeGetSeconds(ThisApp.Input.Device.ExposureDuration);
                    var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration), ExposureMinimumDuration);
                    var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
                    var p          = (newDurationSeconds - minDurationSeconds) / (maxDurationSeconds - minDurationSeconds);
                    Duration.Value = (float)Math.Pow(p, 1.0f / ExposureDurationPower);
                });

                ISO.BeginInvokeOnMainThread(() => {
                    ISO.Value = ThisApp.Input.Device.ISO;
                });

                Bias.BeginInvokeOnMainThread(() => {
                    Bias.Value = ThisApp.Input.Device.ExposureTargetBias;
                });
            };

            // Watch for value changes
            Segments.ValueChanged += (object sender, EventArgs e) => {
                // Lock device for change
                if (ThisApp.CaptureDevice.LockForConfiguration(out Error))
                {
                    // Take action based on the segment selected
                    switch (Segments.SelectedSegment)
                    {
                    case 0:
                        // Activate auto exposure and start monitoring position
                        Duration.Enabled = false;
                        ISO.Enabled      = false;
                        ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                        SampleTimer.Start();
                        Automatic = true;
                        break;

                    case 1:
                        // Lock exposure and allow the user to control the camera
                        SampleTimer.Stop();
                        ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Locked;
                        Automatic        = false;
                        Duration.Enabled = false;
                        ISO.Enabled      = false;
                        break;

                    case 2:
                        // Custom exposure and allow the user to control the camera
                        SampleTimer.Stop();
                        ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Custom;
                        Automatic        = false;
                        Duration.Enabled = true;
                        ISO.Enabled      = true;
                        break;
                    }

                    // Unlock device
                    ThisApp.CaptureDevice.UnlockForConfiguration();
                }
            };

            // Monitor position changes
            Duration.ValueChanged += (object sender, EventArgs e) => {
                // If we are in the automatic mode, ignore changes
                if (Automatic)
                {
                    return;
                }

                // Calculate value
                var p = Math.Pow(Duration.Value, ExposureDurationPower);
                var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration), ExposureMinimumDuration);
                var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
                var newDurationSeconds = p * (maxDurationSeconds - minDurationSeconds) + minDurationSeconds;

                // Update Focus position
                if (ThisApp.CaptureDevice.LockForConfiguration(out Error))
                {
                    ThisApp.CaptureDevice.LockExposure(CMTime.FromSeconds(p, 1000 * 1000 * 1000), ThisApp.CaptureDevice.ISO, null);
                    ThisApp.CaptureDevice.UnlockForConfiguration();
                }
            };

            ISO.ValueChanged += (object sender, EventArgs e) => {
                // If we are in the automatic mode, ignore changes
                if (Automatic)
                {
                    return;
                }

                // Update Focus position
                if (ThisApp.CaptureDevice.LockForConfiguration(out Error))
                {
                    ThisApp.CaptureDevice.LockExposure(ThisApp.CaptureDevice.ExposureDuration, ISO.Value, null);
                    ThisApp.CaptureDevice.UnlockForConfiguration();
                }
            };

            Bias.ValueChanged += (object sender, EventArgs e) => {
                // If we are in the automatic mode, ignore changes
                // if (Automatic) return;

                // Update Focus position
                if (ThisApp.CaptureDevice.LockForConfiguration(out Error))
                {
                    ThisApp.CaptureDevice.SetExposureTargetBias(Bias.Value, null);
                    ThisApp.CaptureDevice.UnlockForConfiguration();
                }
            };
        }