Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Move toolbar items with priority = 0 to LeftBarButtonItems on iOS with Xamarin Forms. Originally written by Murally at http://forums.xamarin.com/discussion/21004/navigation-bar-left-toolbar-button
[assembly: ExportRenderer(typeof(ContentPage), typeof(ExtendedPageRenderer))]
public class ExtendedPageRenderer : PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var contentPage = this.Element as ContentPage;
if (contentPage == null || NavigationController == null)
{
return;
}
var itemsInfo = contentPage.ToolbarItems;
var navigationItem = this.NavigationController.TopViewController.NavigationItem;
var leftNativeButtons = (navigationItem.LeftBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
var rightNativeButtons = (navigationItem.RightBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
rightNativeButtons.ForEach(nativeItem =>
{
// [Hack] Get Xamarin private field "item"
var field = nativeItem.GetType().GetField("item", BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null)
{
return;
}
var info = field.GetValue(nativeItem) as ToolbarItem;
if (info != null && info.Priority != 0)
{
return;
}
rightNativeButtons.Remove(nativeItem);
leftNativeButtons.Add(nativeItem);
});
navigationItem.RightBarButtonItems = rightNativeButtons.ToArray();
navigationItem.LeftBarButtonItems = leftNativeButtons.ToArray();
}
}
@xleon

This comment has been minimized.

Copy link

commented Feb 23, 2015

Thanks for this, it´s working correctly. Very helpful

@Uddhao

This comment has been minimized.

Copy link

commented Mar 18, 2015

Hi,
how to get xamarin private field "item" ?
I used nativeitem.Title but it's not working for me, so I used "clicked" and its working but creating problem in tabbed page, it's added menu buttons repeatedly every time when click on tab.
Please let me know how to figure it.

@KeesAlderliesten

This comment has been minimized.

Copy link

commented Jul 27, 2015

With two buttons (one left and one right) I get an 'Collection modified' exception after the Remove(nativeItem).
I got this working by creating a new List for the right items:

        var leftNativeButtons = (navigationItem.LeftBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
        var rightNativeButtons = (navigationItem.RightBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
        var rightNativeButtonsNew = new UIBarButtonItem[] { }.ToList();

Then before the returns I added:

rightNativeButtonsNew.Add(nativeItem);

and removed

 rightNativeButtons.Remove(nativeItem);

and in the end changed this line

   navigationItem.RightBarButtonItems = rightNativeButtonsNew.ToArray();

This prevents the exception...

@SmartyP

This comment has been minimized.

Copy link

commented Jan 27, 2016

I modified the code to build new collections instead of modifying the existing collections to avoid the Collection Modified exceptions as mentioned by @KeesAlderliesten.

https://gist.github.com/SmartyP/1b0ef834fb757baa51c2

@sfmskywalker

This comment has been minimized.

Copy link

commented Mar 23, 2016

To prevent the Collection Modified Exception, simply do a ToList before the ForEach, like so:

rightNativeButtons.ToList().ForEach(nativeItem =>

This works because now you're iterating over a copy of the list.

@blocksninja

This comment has been minimized.

Copy link

commented Apr 20, 2016

Just started using XF-2.2.0* and noticed the private field has been renamed to _item.
So, on line 24 rename "item" to "_item". Then it's working fine again.

And by the way, thanks for this peace of code! It's the best way to move the toolbaritem so far!

@vahidkadivar

This comment has been minimized.

Copy link

commented Feb 13, 2017

How about this such as render for Android ? is possible to Arranged toolbar item to Left even order as secondary ?

@BenDevelopment

This comment has been minimized.

Copy link

commented May 10, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.