Xamarin.forms: [Enhancement] Left-aligned ToolbarItems on Android & iOS

Created on 27 Jan 2018  Â·  31Comments  Â·  Source: xamarin/Xamarin.Forms

Rationale

ToolbarItems currently display aligned to the right on all platforms. There is no way to display a ToolbarItem on the left. This is useful for many designs, including completely customizing the back button on a NavigationPage.

Implementation

Add new platform specific properties to ToolbarItem:

public enum ToolbarItemPosition { Start, End }

ToolbarItem.On<Android>().ToolbarItemPosition = ToolbarItemPosition.Start;
ToolbarItem.On<iOS>().ToolbarItemPosition = ToolbarItemPosition.Start;

Renderers will need to be updated accordingly.

Expected Result

Android

  • ToolbarItemPosition will default to End.
  • If the ToolbarItemPosition is set to Start, ToolbarItem will be displayed on the left side of the screen when in LTR mode and on the right side of the screen when in RTL mode.

iOS

See Android

UWP

No change. This is not a supported paradigm for UWP, so it will not be affected.

Implications for CSS

None

Backward Compatibility

Since we are adding new properties, there should be no compatibility problems as long as:

  1. We ensure that a ToolbarItem's Position defaults to the right side of the screen, as is the expected behavior now.
  2. We ensure that any Effects or Custom Renderers that may have been created to produce this behavior take precedence over any values that we set, to the best of our ability.

Third party renderers will need to be updated to ensure that this functionality is officially supported.

Difficulty : Easy

See https://forums.xamarin.com/discussion/85097/left-toolbaritems-in-xamarin-forms for original proposal.

F100 toolbar community-sprint high impact proposal-open enhancement âž•

Most helpful comment

any update for this enhancement?

All 31 comments

Hi, i would like to see if i can deal with this issue

@samhouts will this allow both left and right toolbar items? we need the ability to have both.

below is exactly what forms needs to allow

image

@dhaligas Yes, that's the idea.

@netapau you still working on this?

@jassmith
I think someone a little more experienced should take it.
I was able to advance to the creation of the enumeration and modification of ToolbarItem
Here are my questions:

  • Do you have to make new renderers?
  • Do we have to work at Page.cs?

For the first time I look in this code I can not advance anymore.

The answers are no and no to both, though the second would be ideally a yes for an optimal implementation. I have moved this back to the available for implementation column

@jassmith i need this .. do I have to modify the NavigationPageRenderer (Android) to make this work?

@dhaligas the implementation of this for iOS is straightforward and similar on Android

1) Implement the PlatformSpecific API as shown in the spec.

2) Go to https://github.com/xamarin/Xamarin.Forms/blob/6668ff6458b8587a39333ce1ca5fd6ae5f285a7e/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs#L1008 and modify such that there are now 3 lists. The primaries list needs to be split into two lists based on the whether it is "start" or "end". The "end" list goes into where it goes normally:

NavigationItem.SetRightBarButtonItems(primaries == null ? new UIBarButtonItem[0] : primaries.ToArray(), false);

and the start list would basically be a duplicate of that line of code, but instead calling SetLeftBarButtonItems

This is such an easy issue it will surely be picked up by the team or myself very soon now that its in the F100 list which gives us approval to do it.

@jassmith the iOS one seems simple and I am able to do it without modifying the core. But android seems like you have to get into the internals of NavigationPageRenderer to support this

For Android it's basically the same as @jassmith describes, but then here I guess?

https://github.com/xamarin/Xamarin.Forms/blob/c18e85ee434d7bacb730215fecf15acc0230917f/Xamarin.Forms.Platform.Android/Platform.cs#L383

_edit:_ I have taken a quick look at it, but I can't see any way to achieve this on Android? Besides building a custom toolbar, but I figure that will open up some kind of Pandora's box with current (backwards) compatibility

@jfversluis on android there is the Toolbar.NavigationIcon that can be used to set the Left Toolbar Item but that is buried in the NavigationPageRenderer. This only allows one item which is fine for left Left Toolbar Items the majority of the time

@dhaligas I didn't really look into it, but NavigationIcon sounds like it can hold just one?

Upon further review I was too hasty with my statements about Android. The API will need to be modified to only allow one icon for Android and to make it clear its an override for the back button.

@jassmith I have to do this now. is there a way to hack this in on Android with a renderer or effect?

If there is a custom renderer we can write to do this, it would be optimal. i am in desperate need for it.

Is it possible to add options to set the Toolbaricon?

Left, Middle, Right ? It would be more easy to set an image icon of a company in the center of the Navbar or align it to the left Controlbutton (Back or Hamburger)

their is a custom renderer for ContentPage in order to move toolbar items to the left [iOS only],
so, If using the same logic for TabbedRenderer in order to move toolbar items to left when using tabbedpage, the following behavior happened:

when the app first lunch, every thing is fine, but when navigate to other tab, the items on left duplicate on the right,

and till now I can't fix this issue, and I think the problem in these lines

https://github.com/xamarin/Xamarin.Forms/blob/8ed7a287ed9a476bb61e47c11cc9a2d15d8b0526/Xamarin.Forms.Platform.iOS/Renderers/TabbedRenderer.cs#L172-L176

I don't know exactly but please keep this in mind when implementing this feature

Learnings from the shell branch are that this will 100% not work as specced. We need to take the API back to the drawing board here and make sure it reflects the actual capabilities of the platforms.

any update for this enhancement?

Would love it if this can be made to happen, or at least if anyone has the CustomRenderer code for Android. I've got pages where I need Save and Cancel buttons, and if the user, clicks Cancel, I need to show a confirmation that they really want to leave and lose unsaved data...

@Osmosis311 did you try TitleView?

@Osmosis311 did you try TitleView?

they are difference things @shaboo

yea I think these different things, toolbar position is very important to release it as soon as possible

Any Idea if this will be implemented?

Any luck?

Pls implementation!

Pls implementation!

I'm just in the need of it again :( Any updates on this one?

Sorry to hear that @winterdouglas! I'm afraid not.

Although the initial spec still states this as easy, I don't think it is. From what I remember looking into it, iOS for example only allows 1 button on the left. And from Jasons comments it looks like it's not that easy on Android as well. Maybe the APIs changed meanwhile, that would be awesome, I'm happy to be proven wrong in this case :)

That would mean, in order to achieve this, we would have to create a fully customized Navigation bar/page ourselves which is a huge investment to get right. One alternative could be to use the TitleView as suggested. Or if you have any other suggestions to make this happen, I'm all ears.

it's works for me

[assembly: ExportRenderer(typeof(CustomBackButtonPage), typeof(CustomContentPageRenderer))]
namespace SMC.BackButton.iOS.Renderer
public class CustomContentPageRenderer : PageRenderer
{
public static bool pushPage = false;
public static bool closePage = false;

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        try
        {


            var root = this.NavigationController.TopViewController;

            var icon = UIImage.FromBundle("ico_freq_off.png");

            root.NavigationItem.SetLeftBarButtonItem(new UIBarButtonItem(icon, UIBarButtonItemStyle.Plain, (sender, args) =>
            {
                MessagingCenter.Send<object>(this, "ClosePAge");
            }), false);



        }
        catch (Exception e)
        {
            closePage = false;
            pushPage = false;
        }
    }




}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jgold6 picture jgold6  Â·  3Comments

Hudhud picture Hudhud  Â·  3Comments

EmilAlipiev picture EmilAlipiev  Â·  3Comments

joseluisct picture joseluisct  Â·  3Comments

suihanhbr picture suihanhbr  Â·  3Comments