void OnRunningChanged(NSObservedChange change) { var running = ((NSNumber)change.NewValue).BoolValue; if (!running) { return; } DispatchQueue.MainQueue.DispatchAsync(() => { // If the region of interest view's region of interest has not // been initialized yet, let's set an inital region of interest // that is 80% of the shortest side by 25% of the longest side // and centered in the root view. if (RegionOfInterest.IsEmpty) { var width = NMath.Min(Frame.Width, Frame.Height) * 0.8f; var height = NMath.Max(Frame.Width, Frame.Height) * 0.25f; var newRegionOfInterest = Frame.Inset(Frame.GetMidX() - width / 2, Frame.GetMidY() - height / 2); SetRegionOfInterestWithProposedRegionOfInterest(newRegionOfInterest); } if (running) { SetRegionOfInterestWithProposedRegionOfInterest(RegionOfInterest); RegionOfInterestDidChange?.Invoke(this, EventArgs.Empty); } }); }
void ResizeRegionOfInterestWithGestureRecognizer(UIPanGestureRecognizer pan) { var touchLocation = pan.LocationInView(pan.View); var oldRegionOfInterest = RegionOfInterest; switch (pan.State) { case UIGestureRecognizerState.Began: // When the gesture begins, save the corner that is closes to // the resize region of interest gesture recognizer's touch location. currentControlCorner = CornerOfRect(oldRegionOfInterest, touchLocation); break; case UIGestureRecognizerState.Changed: var newRegionOfInterest = oldRegionOfInterest; switch (currentControlCorner) { case ControlCorner.None: // Update the new region of interest with the gesture recognizer's translation. var translation = pan.TranslationInView(pan.View); // Move the region of interest with the gesture recognizer's translation. if (RegionOfInterest.Contains(touchLocation)) { newRegionOfInterest.X += translation.X; newRegionOfInterest.Y += translation.Y; } // If the touch location goes outside the preview layer, // we will only translate the region of interest in the // plane that is not out of bounds. var normalizedRect = new CGRect(0, 0, 1, 1); if (!normalizedRect.Contains(VideoPreviewLayer.PointForCaptureDevicePointOfInterest(touchLocation))) { if (touchLocation.X < RegionOfInterest.GetMinX() || touchLocation.X > RegionOfInterest.GetMaxX()) { newRegionOfInterest.Y += translation.Y; } else if (touchLocation.Y < RegionOfInterest.GetMinY() || touchLocation.Y > RegionOfInterest.GetMaxY()) { newRegionOfInterest.X += translation.X; } } // Set the translation to be zero so that the new gesture // recognizer's translation is in respect to the region of // interest's new position. pan.SetTranslation(CGPoint.Empty, pan.View); break; case ControlCorner.TopLeft: newRegionOfInterest = new CGRect(touchLocation.X, touchLocation.Y, oldRegionOfInterest.Width + oldRegionOfInterest.X - touchLocation.X, oldRegionOfInterest.Height + oldRegionOfInterest.Y - touchLocation.Y); break; case ControlCorner.TopRight: newRegionOfInterest = new CGRect(newRegionOfInterest.X, touchLocation.Y, touchLocation.X - newRegionOfInterest.X, oldRegionOfInterest.Height + newRegionOfInterest.Y - touchLocation.Y); break; case ControlCorner.BottomLeft: newRegionOfInterest = new CGRect(touchLocation.X, oldRegionOfInterest.Y, oldRegionOfInterest.Width + oldRegionOfInterest.X - touchLocation.X, touchLocation.Y - oldRegionOfInterest.Y); break; case ControlCorner.BottomRight: newRegionOfInterest = new CGRect(oldRegionOfInterest.X, oldRegionOfInterest.Y, touchLocation.X - oldRegionOfInterest.X, touchLocation.Y - oldRegionOfInterest.Y); break; } // Update the region of intresest with a valid CGRect. SetRegionOfInterestWithProposedRegionOfInterest(newRegionOfInterest); break; case UIGestureRecognizerState.Ended: RegionOfInterestDidChange?.Invoke(this, EventArgs.Empty); // Reset the current corner reference to none now that the resize. // gesture recognizer has ended. currentControlCorner = ControlCorner.None; break; default: return; } }