internal void SetCoreBounds(UIKit.UIWindow keyWindow, Foundation.Rect windowBounds) { var statusBarHeight = UIApplication.SharedApplication.StatusBarFrame.Size.Height; UIEdgeInsets inset = new UIEdgeInsets(statusBarHeight, 0, 0, 0); // Not respecting its own documentation. https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc // iOS returns all zeros for SafeAreaInsets on non-iPhoneX phones. (ignoring nav bars or status bars) // For that reason, we will set the window's visible bounds to the SafeAreaInsets only for iPhones with notches, // other phones will have insets that consider the status bar if (UseSafeAreaInsets) { if (keyWindow.SafeAreaInsets != UIEdgeInsets.Zero) // if we have a notch { inset = keyWindow.SafeAreaInsets; } } VisibleBounds = new Foundation.Rect( x: windowBounds.Left + inset.Left, y: windowBounds.Top + inset.Top, width: windowBounds.Width - inset.Right - inset.Left, height: windowBounds.Height - inset.Top - inset.Bottom ); if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Updated visible bounds {VisibleBounds}, SafeAreaInsets: {inset}"); } VisibleBoundsChanged?.Invoke(this, null); }
internal void SetVisibleBounds(UIKit.UIWindow keyWindow, Foundation.Rect windowBounds) { var inset = UseSafeAreaInsets ? keyWindow.SafeAreaInsets : UIEdgeInsets.Zero; // Not respecting its own documentation. https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc // iOS returns all zeros for SafeAreaInsets on non-iPhones and iOS11. (ignoring nav bars or status bars) // So we need to update the top inset depending of the status bar visibilty on other devices var statusBarHeight = UIApplication.SharedApplication.StatusBarHidden ? 0 : UIApplication.SharedApplication.StatusBarFrame.Size.Height; inset.Top = (nfloat)Math.Max(inset.Top, statusBarHeight); var newVisibleBounds = new Foundation.Rect( x: windowBounds.Left + inset.Left, y: windowBounds.Top + inset.Top, width: windowBounds.Width - inset.Right - inset.Left, height: windowBounds.Height - inset.Top - inset.Bottom ); if (VisibleBounds != newVisibleBounds) { VisibleBounds = newVisibleBounds; if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Updated visible bounds {VisibleBounds}, SafeAreaInsets: {inset}"); } VisibleBoundsChanged?.Invoke(this, null); } }
/// <summary> /// Determines the bounds of the provided view, including the <see cref="UIElement.Clip"/>, using the window coordinate system. /// </summary> private static CGRect GetBounds(_Window window, _View view) { CGRect?finalRect = null; while (view != null) { if (view is _ScrollView) { // We don't support ScrollViewer clipping, because detecting // the scrolling position and adjusting it makes it for unreliable // calculations, for now. view = view.Superview; } else { #if __MACOS__ var viewOnScreen = view.ConvertRectToView(view.Bounds, window.ContentView); #else var viewOnScreen = view.ConvertRectToView(view.Bounds, window); #endif var element = view as FrameworkElement; if (element?.Clip != null) { var clip = element.Clip.Rect.ToCGRect(); // Offset the local clip bounds to get the clip bounds on screen clip.Offset(viewOnScreen.X, viewOnScreen.Y); viewOnScreen.Intersect(clip); } if (finalRect == null) { finalRect = viewOnScreen; } var r2 = finalRect.Value; r2.Intersect(viewOnScreen); finalRect = r2; view = view.Superview; } } return(finalRect.Value); }
internal void SetVisibleBounds(UIKit.UIWindow keyWindow, Foundation.Rect windowBounds) { var inset = UseSafeAreaInsets ? keyWindow.SafeAreaInsets : UIEdgeInsets.Zero; // Not respecting its own documentation. https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc // iOS returns all zeros for SafeAreaInsets on non-iPhones and iOS11. (ignoring nav bars or status bars) // So we need to update the top inset depending of the status bar visibility on other devices var statusBarHeight = UIApplication.SharedApplication.StatusBarHidden ? 0 : UIApplication.SharedApplication.StatusBarFrame.Size.Height; inset.Top = (nfloat)Math.Max(inset.Top, statusBarHeight); var newVisibleBounds = new Foundation.Rect( x: windowBounds.Left + inset.Left, y: windowBounds.Top + inset.Top, width: windowBounds.Width - inset.Right - inset.Left, height: windowBounds.Height - inset.Top - inset.Bottom ); SetVisibleBounds(newVisibleBounds); }