[iOS] fix full width issues for TitleView (#3939)

* [iOS] fix full width issues for TitleView

* [iOS] simplified iOS 10

fixes #3881
fixes #3679
This commit is contained in:
Shane Neuville 2018-10-01 11:53:47 -06:00 коммит произвёл Samantha Houts
Родитель 16a4e91aac
Коммит 379adeb380
4 изменённых файлов: 501 добавлений и 192 удалений

Просмотреть файл

@ -387,7 +387,7 @@ namespace Xamarin.Forms.Controls
if (navigationBehavior == NavigationBehavior.PushAsync && rootPage.GetType () == typeof (CoreNavigationPage))
{
_pages.Insert (0, new GalleryPageFactory(() => new NavigationBarGallery((NavigationPage)rootPage), "NavigationBar Gallery - Legacy"));
_pages.Insert(1, new GalleryPageFactory(() => new TitleView(), "TitleView"));
_pages.Insert(1, new GalleryPageFactory(() => new TitleView(true), "TitleView"));
}
var template = new DataTemplate(typeof(TextCell));

Просмотреть файл

@ -1,19 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Controls.GalleryPages.TitleView">
<NavigationPage.TitleView>
<StackLayout>
<StackLayout BackgroundColor="Pink">
<Label Text="This is my TitleView" />
<Label Text="I can be a subtitle" />
</StackLayout>
</NavigationPage.TitleView>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
<ScrollView>
<StackLayout BackgroundColor="Pink">
<Button Clicked="masterDetailsPage_Clicked" Text="Master Details Page"></Button>
<Button Clicked="masterDetailsPageIcon_Clicked" Text="Toggle MDP Icon"></Button>
<Button Clicked="tabbedPage_Clicked" Text="Tabbed Page"></Button>
<Button Clicked="navigationPage_Clicked" Text="Navigation Page"></Button>
<Button Clicked="nextPage_Clicked" Text="Push a Page"></Button>
<Button Clicked="titleIcon_Clicked" Text="Toggle Title Icon"></Button>
<Button Clicked="toggleToolBarItem_Clicked" Text="Toggle Tool Bar Item" ></Button>
<Button Clicked="toggleSecondaryToolBarItem_Clicked" Text="Toggle Secondary Tool Bar Item" ></Button>
<Button Clicked="toggleLargeTitles_Clicked" Text="Toggle Large Titles" ></Button>
<Button Clicked="changeTitleView_Clicked" Text="Toggle Different Title Views"></Button>
<Button x:Name="btnToggleBackButtonTitle" Clicked="toggleBackButtonText_Clicked" Text="Toggle Back Button Title Text"></Button>
<Button Clicked="backToGallery_Clicked" Text="Back to Gallery"></Button>
</StackLayout>
</ScrollView>
</ContentPage>

Просмотреть файл

@ -5,6 +5,8 @@ using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
using Xamarin.Forms.Xaml;
namespace Xamarin.Forms.Controls.GalleryPages
@ -12,9 +14,216 @@ namespace Xamarin.Forms.Controls.GalleryPages
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TitleView : ContentPage
{
public TitleView ()
public TitleView(bool initialLoad)
{
InitializeComponent ();
InitializeComponent();
if (initialLoad)
{
Device.BeginInvokeOnMainThread(() => masterDetailsPage_Clicked(this, EventArgs.Empty));
}
}
NavigationPage CreateNavigationPage()
{
return new NavigationPage(new TitleView(false) { Title = "Nav Title" });
}
public Page GetPage()
{
return new MasterDetailPage()
{
Detail = CreateNavigationPage(),
Master = new ContentPage() { Title = "Master" }
};
}
void masterDetailsPage_Clicked(object sender, EventArgs e)
{
App.Current.MainPage =
new MasterDetailPage()
{
Detail = CreateNavigationPage(),
Master = new ContentPage() { Title = "Master" },
};
}
void toggleBackButtonText_Clicked(object sender, EventArgs e)
{
var page = Navigation.NavigationStack.First();
var titleText = NavigationPage.GetBackButtonTitle(page);
if (titleText == null)
titleText = "Custom Text";
else if (titleText == "Custom Text")
titleText = "";
else
titleText = null;
NavigationPage.SetBackButtonTitle(page, titleText);
changeTitleView_Clicked(this, EventArgs.Empty);
string result = (titleText == null) ? "<null>" : titleText;
btnToggleBackButtonTitle.Text = $"Toggle Back Button Title Text: {result}";
}
void tabbedPage_Clicked(object sender, EventArgs e)
{
var page = new ContentPage() { Title = "other title page" };
NavigationPage.SetTitleView(page, createGrid());
App.Current.MainPage =
new TabbedPage()
{
Children =
{
CreateNavigationPage(),
new ContentPage(){ Title = "no title Page"},
new NavigationPage(page),
}
};
}
void navigationPage_Clicked(object sender, EventArgs e)
{
App.Current.MainPage = CreateNavigationPage();
}
void nextPage_Clicked(object sender, EventArgs e)
{
ContentPage page = null;
page = new ContentPage()
{
Title = "second page",
Content = new StackLayout()
{
Children =
{
new Button()
{
Text = "Toggle Back Button",
Command = new Command(()=>
{
NavigationPage.SetHasBackButton(page, !NavigationPage.GetHasBackButton(page));
})
},
new Button()
{
Text = "Toggle Title View",
Command = new Command(()=>
{
changeTitleView_Clicked(page, EventArgs.Empty);
})
}
}
}
};
NavigationPage.SetTitleView(page, createGrid());
Navigation.PushAsync(page);
}
View createSearchBarView()
{
return new SearchBar { BackgroundColor = Color.Cornsilk, HorizontalOptions = LayoutOptions.FillAndExpand, Margin = new Thickness(10, 0) };
}
View createGrid()
{
var grid = new Grid
{
BackgroundColor = Color.LightGray
};
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
var label = new Label { Text = "hello", HorizontalOptions = LayoutOptions.Start, BackgroundColor = Color.Yellow };
var label2 = new Label { Text = "hello 2", HorizontalOptions = LayoutOptions.Start, BackgroundColor = Color.Yellow };
grid.Children.Add(label);
grid.Children.Add(label2);
Grid.SetRow(label2, 1);
var label3 = new Label { Text = "right aligned", HorizontalTextAlignment = TextAlignment.End };
Grid.SetColumn(label3, 1);
grid.Children.Add(label3);
return grid;
}
void titleIcon_Clicked(object sender, EventArgs e)
{
var titleIcon = NavigationPage.GetTitleIcon(this);
if (titleIcon == null)
NavigationPage.SetTitleIcon(this, "coffee.png");
else
NavigationPage.SetTitleIcon(this, null);
}
void masterDetailsPageIcon_Clicked(object sender, EventArgs e)
{
if (App.Current.MainPage is MasterDetailPage mdp)
{
if (String.IsNullOrWhiteSpace(mdp.Master.Icon))
mdp.Master.Icon = "menuIcon";
else
mdp.Master.Icon = null;
}
}
void toggleLargeTitles_Clicked(object sender, EventArgs e)
{
var navPage = (NavigationPage)Navigation.NavigationStack.Last().Parent;
navPage.On<iOS>().SetPrefersLargeTitles(!navPage.On<iOS>().PrefersLargeTitles());
}
void backToGallery_Clicked(object sender, EventArgs e)
{
(App.Current as App).Reset();
}
void toggleToolBarItem_Clicked(object sender, EventArgs e)
{
var page = Navigation.NavigationStack.Last();
var items = page.ToolbarItems.Where(x => x.Order == ToolbarItemOrder.Primary).ToList();
if (items.Any())
foreach (var item in items)
page.ToolbarItems.Remove(item);
else
page.ToolbarItems.Add(new ToolbarItem() { Text = "Save", Order = ToolbarItemOrder.Primary });
}
void toggleSecondaryToolBarItem_Clicked(object sender, EventArgs e)
{
var page = Navigation.NavigationStack.Last();
var items = page.ToolbarItems.Where(x => x.Order == ToolbarItemOrder.Secondary).ToList();
if (items.Any())
foreach (var item in items)
page.ToolbarItems.Remove(item);
else
page.ToolbarItems.Add(new ToolbarItem() { Text = "Save", Order = ToolbarItemOrder.Secondary });
}
void changeTitleView_Clicked(object sender, EventArgs e)
{
var currentView = NavigationPage.GetTitleView(Navigation.NavigationStack.Last());
if (currentView is Grid)
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), createSearchBarView());
else if (currentView is SearchBar)
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), null);
else
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), createGrid());
}
}
}

Просмотреть файл

@ -33,14 +33,14 @@ namespace Xamarin.Forms.Platform.iOS
UIImage _defaultNavBarShadowImage;
UIImage _defaultNavBarBackImage;
public NavigationRenderer()
public NavigationRenderer() : base(typeof(FormsNavigationBar), null)
{
MessagingCenter.Subscribe<IVisualElementRenderer>(this, UpdateToolbarButtons, sender =>
{
if (!ViewControllers.Any())
return;
var parentingViewController = (ParentingViewController)ViewControllers.Last();
UpdateLeftBarButtonItem(parentingViewController);
parentingViewController?.UpdateLeftBarButtonItem();
});
}
@ -97,7 +97,7 @@ namespace Xamarin.Forms.Platform.iOS
View.SetNeedsLayout();
var parentingViewController = (ParentingViewController)ViewControllers.Last();
UpdateLeftBarButtonItem(parentingViewController);
parentingViewController?.UpdateLeftBarButtonItem();
}
public Task<bool> PopToRootAsync(Page page, bool animated = true)
@ -356,7 +356,7 @@ namespace Xamarin.Forms.Platform.iOS
// otherwise the view controller is forced to 0,0
var pack = new ParentingViewController(this) { Child = page };
UpdateTitleArea(pack, page);
pack.UpdateTitleArea(page);
var pageRenderer = Platform.GetRenderer(page);
pack.View.AddSubview(pageRenderer.ViewController.View);
@ -450,7 +450,7 @@ namespace Xamarin.Forms.Platform.iOS
else if (e.PropertyName == NavigationPage.BackButtonTitleProperty.PropertyName)
{
var pack = (ParentingViewController)TopViewController;
UpdateTitleArea(pack, pack.Child);
pack?.UpdateTitleArea(pack.Child);
}
else if (e.PropertyName == HideNavigationBarSeparatorProperty.PropertyName)
{
@ -462,7 +462,7 @@ namespace Xamarin.Forms.Platform.iOS
{
//if the last time we did ViewDidLayoutSubviews we had other value for _hasNavigationBar
//we will need to relayout. This is because Current is updated async of the layout happening
if(_hasNavigationBar != NavigationPage.GetHasNavigationBar(newCurrentPage))
if (_hasNavigationBar != NavigationPage.GetHasNavigationBar(newCurrentPage))
ViewDidLayoutSubviews();
}
@ -507,118 +507,6 @@ namespace Xamarin.Forms.Platform.iOS
NavigationBar.PrefersLargeTitles = NavPage.OnThisPlatform().PrefersLargeTitles();
}
void UpdateTitleArea(ParentingViewController pack, Page page)
{
if (pack == null || page == null)
return;
if (!string.IsNullOrWhiteSpace(page.Title))
pack.NavigationItem.Title = page.Title;
// First page and we have a master detail to contend with
UpdateLeftBarButtonItem(pack);
var titleText = NavigationPage.GetBackButtonTitle(page);
if (titleText != null)
{
// adding a custom event handler to UIBarButtonItem for navigating back seems to be ignored.
pack.NavigationItem.BackBarButtonItem = new UIBarButtonItem { Title = titleText, Style = UIBarButtonItemStyle.Plain };
}
FileImageSource titleIcon = NavigationPage.GetTitleIcon(page);
VisualElement titleView = NavigationPage.GetTitleView(page);
ClearTitleViewContainer(pack);
bool needContainer = titleView != null || titleIcon != null;
if (needContainer)
{
Container titleViewContainer = new Container();
pack.NavigationItem.TitleView = titleViewContainer;
UpdateTitleImage(titleViewContainer, titleIcon);
UpdateTitleView(titleViewContainer, titleView);
// Need to call this for iOS10 to properly frame the renderer
TopViewController?.NavigationItem?.TitleView?.SizeToFit();
TopViewController?.NavigationItem?.TitleView?.LayoutSubviews();
}
}
async void UpdateTitleImage(Container titleViewContainer, FileImageSource titleIcon)
{
if (titleViewContainer == null)
return;
if (string.IsNullOrWhiteSpace(titleIcon))
{
titleViewContainer.Icon = null;
}
else
{
var source = Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler>(titleIcon);
var image = await source.LoadImageAsync(titleIcon);
try
{
titleViewContainer.Icon = new UIImageView(image) { };
}
catch
{
//UIImage ctor throws on file not found if MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure is true;
}
}
}
void ClearTitleViewContainer(UIViewController pack)
{
if (pack == null)
return;
if (pack.NavigationItem.TitleView != null && pack.NavigationItem.TitleView is Container titleViewContainer)
{
titleViewContainer.Dispose();
titleViewContainer = null;
pack.NavigationItem.TitleView = null;
}
}
void UpdateTitleView(Container titleViewContainer, VisualElement titleView)
{
if (titleViewContainer == null)
return;
var titleViewRenderer = titleViewContainer.Child;
if (titleView != null)
{
if (titleViewRenderer != null)
{
var rendererType = titleViewRenderer is System.Reflection.IReflectableType reflectableType
? reflectableType.GetTypeInfo().AsType()
: titleViewRenderer.GetType();
if (titleView != null && rendererType == Internals.Registrar.Registered.GetHandlerTypeForObject(titleView))
{
if (titleViewContainer != null)
titleViewContainer.Child = null;
titleViewRenderer.SetElement(titleView);
return;
}
titleViewContainer?.DisposeChild();
}
titleViewRenderer = Platform.CreateRenderer(titleView);
titleViewContainer.Child = titleViewRenderer;
}
else if (titleViewRenderer != null)
{
titleViewContainer?.DisposeChild();
}
}
void UpdateTranslucent()
{
NavigationBar.Translucent = NavPage.OnThisPlatform().IsNavigationBarTranslucent();
@ -695,7 +583,7 @@ namespace Xamarin.Forms.Platform.iOS
ViewControllers = _removeControllers;
}
var parentingViewController = ViewControllers.Last() as ParentingViewController;
UpdateLeftBarButtonItem(parentingViewController, page);
parentingViewController?.UpdateLeftBarButtonItem(page);
}
void RemoveViewControllers(bool animated)
@ -794,17 +682,6 @@ namespace Xamarin.Forms.Platform.iOS
}
}
void UpdateLeftBarButtonItem(ParentingViewController containerController, Page pageBeingRemoved = null)
{
if (containerController == null)
return;
var currentChild = containerController.Child;
var firstPage = NavPage.Pages.FirstOrDefault();
if ((firstPage != pageBeingRemoved && currentChild != firstPage && NavigationPage.GetHasBackButton(currentChild)) || _parentMasterDetailPage == null)
return;
SetMasterLeftBarButton(containerController, _parentMasterDetailPage);
}
void UpdateTint()
{
@ -1103,10 +980,117 @@ namespace Xamarin.Forms.Platform.iOS
UpdateLargeTitles();
else if (e.PropertyName == NavigationPage.TitleIconProperty.PropertyName ||
e.PropertyName == NavigationPage.TitleViewProperty.PropertyName)
UpdateTitleArea(Child);
}
internal void UpdateLeftBarButtonItem(Page pageBeingRemoved = null)
{
NavigationRenderer n;
if (!_navigation.TryGetTarget(out n))
return;
var currentChild = this.Child;
var firstPage = n.NavPage.Pages.FirstOrDefault();
if (n._parentMasterDetailPage == null)
return;
if (firstPage != pageBeingRemoved && currentChild != firstPage && NavigationPage.GetHasBackButton(currentChild))
{
NavigationItem.LeftBarButtonItem = null;
return;
}
SetMasterLeftBarButton(this, n._parentMasterDetailPage);
}
public bool NeedsTitleViewContainer(Page page) => NavigationPage.GetTitleIcon(page) != null || NavigationPage.GetTitleView(page) != null;
internal void UpdateBackButtonTitle(Page page) => UpdateBackButtonTitle(page.Title, NavigationPage.GetBackButtonTitle(page));
internal void UpdateBackButtonTitle(string title, string backButtonTitle)
{
if (!string.IsNullOrWhiteSpace(title))
NavigationItem.Title = title;
if (backButtonTitle != null)
// adding a custom event handler to UIBarButtonItem for navigating back seems to be ignored.
NavigationItem.BackBarButtonItem = new UIBarButtonItem { Title = backButtonTitle, Style = UIBarButtonItemStyle.Plain };
else
NavigationItem.BackBarButtonItem = null;
}
internal void UpdateTitleArea(Page page)
{
if (page == null)
return;
FileImageSource titleIcon = NavigationPage.GetTitleIcon(page);
View titleView = NavigationPage.GetTitleView(page);
bool needContainer = titleView != null || titleIcon != null;
string backButtonText = NavigationPage.GetBackButtonTitle(page);
bool isBackButtonTextSet = page.IsSet(NavigationPage.BackButtonTitleProperty);
// on iOS 10 if the user hasn't set the back button text
// we set it to an empty string so it's consistent with iOS 11
if (!Forms.IsiOS11OrNewer && !isBackButtonTextSet)
backButtonText = "";
// First page and we have a master detail to contend with
UpdateLeftBarButtonItem();
UpdateBackButtonTitle(page.Title, backButtonText);
//var hadTitleView = NavigationItem.TitleView != null;
ClearTitleViewContainer();
if (needContainer)
{
NavigationRenderer n;
if (_navigation.TryGetTarget(out n))
n.UpdateTitleArea(this, Child);
if (!_navigation.TryGetTarget(out n))
return;
Container titleViewContainer = new Container(titleView, n.NavigationBar);
UpdateTitleImage(titleViewContainer, titleIcon);
NavigationItem.TitleView = titleViewContainer;
}
}
async void UpdateTitleImage(Container titleViewContainer, FileImageSource titleIcon)
{
if (titleViewContainer == null)
return;
if (string.IsNullOrWhiteSpace(titleIcon))
{
titleViewContainer.Icon = null;
}
else
{
var source = Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler>(titleIcon);
var image = await source.LoadImageAsync(titleIcon);
try
{
titleViewContainer.Icon = new UIImageView(image) { };
}
catch
{
//UIImage ctor throws on file not found if MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure is true;
}
}
}
void ClearTitleViewContainer()
{
if (NavigationItem.TitleView != null && NavigationItem.TitleView is Container titleViewContainer)
{
titleViewContainer.Dispose();
titleViewContainer = null;
NavigationItem.TitleView = null;
}
}
@ -1123,10 +1107,17 @@ namespace Xamarin.Forms.Platform.iOS
void UpdateHasBackButton()
{
if (Child == null)
if (Child == null || NavigationItem.HidesBackButton == !NavigationPage.GetHasBackButton(Child))
return;
NavigationItem.HidesBackButton = !NavigationPage.GetHasBackButton(Child);
NavigationRenderer n;
if (!_navigation.TryGetTarget(out n))
return;
if (!Forms.IsiOS11OrNewer || n._parentMasterDetailPage != null)
UpdateTitleArea(Child);
}
void UpdateNavigationBarVisibility(bool animated)
@ -1257,25 +1248,136 @@ namespace Xamarin.Forms.Platform.iOS
VisualElementRenderer<VisualElement>.RegisterEffect(effect, View);
}
internal class FormsNavigationBar : UINavigationBar
{
public FormsNavigationBar() : base()
{
}
public FormsNavigationBar(Foundation.NSCoder coder) : base(coder)
{
}
protected FormsNavigationBar(Foundation.NSObjectFlag t) : base(t)
{
}
protected internal FormsNavigationBar(IntPtr handle) : base(handle)
{
}
public FormsNavigationBar(RectangleF frame) : base(frame)
{
}
public RectangleF BackButtonFrameSize { get; private set; }
public UILabel NavBarLabel { get; private set; }
public override void LayoutSubviews()
{
if (!Forms.IsiOS11OrNewer)
{
for (int i = 0; i < this.Subviews.Length; i++)
{
if (Subviews[i] is UIView view)
{
if (view.Class.Name == "_UINavigationBarBackIndicatorView")
{
if (view.Alpha == 0)
BackButtonFrameSize = CGRect.Empty;
else
BackButtonFrameSize = view.Frame;
break;
}
else if(view.Class.Name == "UINavigationItemButtonView")
{
if (view.Subviews.Length == 0)
NavBarLabel = null;
else if (view.Subviews[0] is UILabel titleLabel)
NavBarLabel = titleLabel;
}
}
}
}
base.LayoutSubviews();
}
}
class Container : UIView
{
View _view;
FormsNavigationBar _bar;
IVisualElementRenderer _child;
UIImageView _icon;
nfloat IconHeight => _icon?.Frame.Height ?? 0;
public Container(View view, UINavigationBar bar) : base(bar.Bounds)
{
if (Forms.IsiOS11OrNewer)
{
TranslatesAutoresizingMaskIntoConstraints = false;
}
else
{
TranslatesAutoresizingMaskIntoConstraints = true;
AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth;
}
_bar = bar as FormsNavigationBar;
if (view != null)
{
_view = view;
_child = Platform.CreateRenderer(view);
Platform.SetRenderer(view, _child);
AddSubview(_child.NativeView);
}
ClipsToBounds = true;
}
public override CGSize IntrinsicContentSize => UILayoutFittingExpandedSize;
nfloat IconHeight => _icon?.Frame.Height ?? 0;
nfloat IconWidth => _icon?.Frame.Width ?? 0;
protected override void Dispose(bool disposing)
// Navigation bar will not stretch past these values. Prevent content clipping.
// iOS11 does this for us automatically, but apparently iOS10 doesn't.
nfloat ToolbarHeight
{
if (disposing)
get
{
DisposeChild();
if (Superview?.Bounds.Height > 0)
return Superview.Bounds.Height;
_icon?.Dispose();
_icon = null;
return (Device.Idiom == TargetIdiom.Phone && Device.Info.CurrentOrientation.IsLandscape()) ? 32 : 44;
}
}
public override CGRect Frame
{
get => base.Frame;
set
{
if (Superview != null)
{
if (!Forms.IsiOS11OrNewer)
{
value.Y = Superview.Bounds.Y;
if (_bar != null && String.IsNullOrWhiteSpace(_bar.NavBarLabel?.Text) && _bar.BackButtonFrameSize != RectangleF.Empty)
{
var xSpace = _bar.BackButtonFrameSize.Width + (_bar.BackButtonFrameSize.X * 2);
value.Width = (value.X - xSpace) + value.Width;
value.X = xSpace;
}
};
value.Height = ToolbarHeight;
}
base.Frame = value;
}
base.Dispose(disposing);
}
public UIImageView Icon
@ -1292,65 +1394,53 @@ namespace Xamarin.Forms.Platform.iOS
}
}
public IVisualElementRenderer Child
{
get { return _child; }
set
{
if (_child != null)
DisposeChild();
_child = value;
if (value != null)
AddSubview(value.NativeView);
}
}
public override SizeF SizeThatFits(SizeF size)
{
IVisualElementRenderer renderer = _child;
if (renderer == null || renderer.Element == null || renderer.Element.Parent == null)
return new SizeF(IconWidth, IconHeight);
var result = renderer.Element.Measure(double.PositiveInfinity, double.PositiveInfinity, MeasureFlags.IncludeMargins);
return new SizeF(result.Request.Width + IconWidth, Math.Max(IconHeight, result.Request.Height));
return new SizeF(size.Width, ToolbarHeight);
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (Frame == CGRect.Empty || Frame.Width >= 10000 || Frame.Height >= 10000)
return;
// Navigation bar will not stretch past these values. Prevent content clipping.
// iOS11 does this for us automatically, but apparently iOS10 doesn't.
int toolbarHeight = 44;
if (Device.Idiom == TargetIdiom.Phone && Device.Info.CurrentOrientation.IsLandscape())
toolbarHeight = 32;
nfloat toolbarHeight = ToolbarHeight;
double height = Math.Min(toolbarHeight, Bounds.Height);
Frame = new RectangleF(Frame.X, Frame.Y, Bounds.Width, height);
if (_icon != null)
_icon.Frame = new RectangleF(0, 0, IconWidth, Math.Min(toolbarHeight, IconHeight));
if (_child?.Element != null)
Layout.LayoutChildIntoBoundingRegion(_child.Element, new Rectangle(IconWidth, 0, Bounds.Width - IconWidth, height));
{
var layoutBounds = new Rectangle(IconWidth, 0, Bounds.Width - IconWidth, height);
if (_child.Element.Bounds != layoutBounds)
Layout.LayoutChildIntoBoundingRegion(_child.Element, layoutBounds);
}
}
public void DisposeChild()
protected override void Dispose(bool disposing)
{
if (_child == null)
return;
if (disposing)
{
if (_child.Element.Platform is Platform platform)
platform.DisposeModelAndChildrenRenderers(_child.Element);
if (_child != null)
{
if (_child.Element.Platform is Platform platform)
platform.DisposeModelAndChildrenRenderers(_child.Element);
_child.NativeView.RemoveFromSuperview();
_child.Dispose();
_child = null;
_child.NativeView.RemoveFromSuperview();
_child.Dispose();
_child = null;
}
_view = null;
_icon?.Dispose();
_icon = null;
}
base.Dispose(disposing);
}
}
}