From 1d8e098e2a85d5f82eeb816f7e12c3c8e9381262 Mon Sep 17 00:00:00 2001 From: adrianknight89 Date: Wed, 15 Feb 2017 05:39:02 -0600 Subject: [PATCH] [iOS] MasterDetailPage master icon should be changeable from any page on the stack (#608) * master detail page master icon could be changed from any page on the stack * change icon names * added titles --- .../Bugzilla32865.cs | 135 +++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 1 + .../Renderers/NavigationRenderer.cs | 61 +++++----- .../Renderers/PhoneMasterDetailRenderer.cs | 15 ++- 4 files changed, 181 insertions(+), 31 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32865.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32865.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32865.cs new file mode 100644 index 0000000..2776952 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32865.cs @@ -0,0 +1,135 @@ +using System; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +// Apply the default category of "Issues" to all of the tests in this assembly +// We use this as a catch-all for tests which haven't been individually categorized +#if UITEST +[assembly: NUnit.Framework.Category("Issues")] +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 32865, "On MasterDetailPage trying to change Icon of Master page doesn\'t work if another view is pushed and Image is renderer in blue", PlatformAffected.iOS)] + public class Bugzilla32865 : TestMasterDetailPage // or TestMasterDetailPage, etc ... + { + public static Bugzilla32865 Mdp; + + protected override void Init() + { + Mdp = this; + + Master = new ContentPage {Title = "Master"}; + Detail = new NavigationPage(new DetailView32865()); + } + + public void ChangeIcon() + { + Master.Icon = "settings"; + } + public void ChangeIcon2() + { + Master.Icon = "menuIcon"; + } + } + + [Preserve(AllMembers = true)] + public class DetailView32865 : ContentPage + { + public DetailView32865() + { + Title = "Page1"; + + var label = new Label + { + Text = "Push a page and then change master icon. The icon should be changeable from any page on the navigation stack.", + HorizontalTextAlignment = TextAlignment.Center, + VerticalTextAlignment = TextAlignment.Center + }; + + var button = new Button() + { + Text = "Icon 1", + }; + button.Clicked += Button_Clicked; + var button2 = new Button() + { + Text = "Icon 2", + }; + button2.Clicked += Button2_Clicked; + var button3 = new Button() + { + Text = "Push Page", + }; + button3.Clicked += Button3_Clicked; + + var layout = new StackLayout() + { + VerticalOptions = LayoutOptions.FillAndExpand, + HorizontalOptions = LayoutOptions.FillAndExpand, + Children = { label, button, button2, button3 }, + }; + Content = layout; + } + void Button3_Clicked(object sender, EventArgs e) + { + Navigation.PushAsync(new DetailView232865()); + } + + void Button_Clicked(object sender, EventArgs e) + { + Bugzilla32865.Mdp.ChangeIcon(); + } + + void Button2_Clicked(object sender, EventArgs e) + { + Bugzilla32865.Mdp.ChangeIcon2(); + } + } + + [Preserve(AllMembers = true)] + public class DetailView232865 : ContentPage + { + public DetailView232865() + { + Title = "Page2"; + + var button = new Button() + { + Text = "Icon 1", + }; + button.Clicked += Button_Clicked; + + var button2 = new Button() + { + Text = "Icon 2", + }; + button2.Clicked += Button2_Clicked; + + var layout = new StackLayout() + { + VerticalOptions = LayoutOptions.FillAndExpand, + HorizontalOptions = LayoutOptions.FillAndExpand, + Children = { button, button2 }, + }; + + Content = layout; + } + + void Button_Clicked(object sender, EventArgs e) + { + Bugzilla32865.Mdp.ChangeIcon(); + } + + void Button2_Clicked(object sender, EventArgs e) + { + Bugzilla32865.Mdp.ChangeIcon2(); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 754133d..b3b1434 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -58,6 +58,7 @@ Code + diff --git a/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs index e742fce..e054a2d 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs @@ -35,8 +35,6 @@ namespace Xamarin.Forms.Platform.iOS var parentingViewController = (ParentingViewController)ViewControllers.Last(); UpdateLeftBarButtonItem(parentingViewController); }); - - } Page Current { get; set; } @@ -621,34 +619,7 @@ namespace Xamarin.Forms.Platform.iOS if ((firstPage != pageBeingRemoved && currentChild != firstPage && NavigationPage.GetHasBackButton(currentChild)) || _parentMasterDetailPage == null) return; - if (!_parentMasterDetailPage.ShouldShowToolbarButton()) - { - containerController.NavigationItem.LeftBarButtonItem = null; - return; - } - - var shouldUseIcon = _parentMasterDetailPage.Master.Icon != null; - if (shouldUseIcon) - { - try - { - containerController.NavigationItem.LeftBarButtonItem = - new UIBarButtonItem(new UIImage(_parentMasterDetailPage.Master.Icon), UIBarButtonItemStyle.Plain, - (o, e) => _parentMasterDetailPage.IsPresented = !_parentMasterDetailPage.IsPresented); - } - catch (Exception) - { - // Throws Exception otherwise would catch more specific exception type - shouldUseIcon = false; - } - } - - if (!shouldUseIcon) - { - containerController.NavigationItem.LeftBarButtonItem = new UIBarButtonItem(_parentMasterDetailPage.Master.Title, - UIBarButtonItemStyle.Plain, - (o, e) => _parentMasterDetailPage.IsPresented = !_parentMasterDetailPage.IsPresented); - } + SetMasterLeftBarButton(containerController, _parentMasterDetailPage); } void UpdateTint() @@ -681,6 +652,36 @@ namespace Xamarin.Forms.Platform.iOS } } + internal static void SetMasterLeftBarButton(UIViewController containerController, MasterDetailPage masterDetailPage) + { + if (!masterDetailPage.ShouldShowToolbarButton()) + { + containerController.NavigationItem.LeftBarButtonItem = null; + return; + } + + EventHandler handler = (o, e) => masterDetailPage.IsPresented = !masterDetailPage.IsPresented; + + bool shouldUseIcon = masterDetailPage.Master.Icon != null; + if (shouldUseIcon) + { + try + { + containerController.NavigationItem.LeftBarButtonItem = new UIBarButtonItem(new UIImage(masterDetailPage.Master.Icon), UIBarButtonItemStyle.Plain, handler); + } + catch (Exception) + { + // Throws Exception otherwise would catch more specific exception type + shouldUseIcon = false; + } + } + + if (!shouldUseIcon) + { + containerController.NavigationItem.LeftBarButtonItem = new UIBarButtonItem(masterDetailPage.Master.Title, UIBarButtonItemStyle.Plain, handler); + } + } + class SecondaryToolbar : UIToolbar { readonly List _lines = new List(); diff --git a/Xamarin.Forms.Platform.iOS/Renderers/PhoneMasterDetailRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/PhoneMasterDetailRenderer.cs index b26e314..fbadc77 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/PhoneMasterDetailRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/PhoneMasterDetailRenderer.cs @@ -218,7 +218,7 @@ namespace Xamarin.Forms.Platform.iOS void HandleMasterPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Page.IconProperty.PropertyName || e.PropertyName == Page.TitleProperty.PropertyName) - MessagingCenter.Send(this, NavigationRenderer.UpdateToolbarButtons); + UpdateLeftBarButton(); } void HandlePropertyChanged(object sender, PropertyChangedEventArgs e) @@ -321,6 +321,19 @@ namespace Xamarin.Forms.Platform.iOS SetNeedsStatusBarAppearanceUpdate(); } + void UpdateLeftBarButton() + { + var masterDetailPage = Element as MasterDetailPage; + if (!(masterDetailPage?.Detail is NavigationPage)) + return; + + var detailRenderer = Platform.GetRenderer(masterDetailPage.Detail) as UINavigationController; + + UIViewController firstPage = detailRenderer?.ViewControllers.FirstOrDefault(); + if (firstPage != null) + NavigationRenderer.SetMasterLeftBarButton(firstPage, masterDetailPage); + } + public override UIViewController ChildViewControllerForStatusBarHidden() { if (((MasterDetailPage)Element).Detail != null) -- 2.7.4