Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Enhancement] Left-aligned ToolbarItems on Android & iOS #1719

Closed
samhouts opened this issue Jan 26, 2018 · 34 comments
Closed

[Enhancement] Left-aligned ToolbarItems on Android & iOS #1719

samhouts opened this issue Jan 26, 2018 · 34 comments

Comments

@samhouts
Copy link
Member

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.

@ghost
Copy link

ghost commented Jan 28, 2018

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

@davidortinau davidortinau self-assigned this Jan 28, 2018
@davidortinau davidortinau added this to In Progress in Enhancements Jan 29, 2018
@hartez hartez removed this from New in Triage Jan 29, 2018
@dhaligas
Copy link

dhaligas commented Feb 8, 2018

@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

@samhouts
Copy link
Member Author

samhouts commented Feb 8, 2018

@dhaligas Yes, that's the idea.

@jassmith
Copy link

@netapau you still working on this?

@ghost
Copy link

ghost commented Feb 17, 2018

@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.

@jassmith
Copy link

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 jassmith moved this from In Progress to Ready for Implementation in Enhancements Feb 17, 2018
@dhaligas
Copy link

dhaligas commented Feb 17, 2018

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

@jassmith
Copy link

jassmith commented Feb 17, 2018

@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

    foreach (var item in _tracker.ToolbarItems)
    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.

@dhaligas
Copy link

@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

@jfversluis
Copy link
Member

jfversluis commented Feb 20, 2018

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

foreach (ToolbarItem item in _toolbarTracker.ToolbarItems)

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

@dhaligas
Copy link

@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

@jfversluis
Copy link
Member

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

@jassmith
Copy link

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 jassmith self-assigned this Feb 21, 2018
@jassmith jassmith moved this from Ready for Implementation to In Progress in Enhancements Feb 21, 2018
@dhaligas
Copy link

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

@smartprogrammer93
Copy link

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

@pnda489
Copy link

pnda489 commented May 14, 2018

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)

@Shaboo
Copy link

Shaboo commented May 22, 2018

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

void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Setting TabBarItem.Title in iOS 10 causes rendering bugs
// Work around this by creating a new UITabBarItem on each change
if (e.PropertyName == Page.TitleProperty.PropertyName && !Forms.IsiOS10OrNewer)

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

@samhouts samhouts moved this from In Progress to Ready for Implementation in Enhancements Jul 26, 2018
@jassmith jassmith removed their assignment Aug 16, 2018
@jassmith
Copy link

jassmith commented Aug 16, 2018

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.

@KennyDizi
Copy link

any update for this enhancement?

@Osmosis311
Copy link

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...

@Shaboo
Copy link

Shaboo commented Jan 15, 2019

@Osmosis311 did you try TitleView?

@KennyDizi
Copy link

@Osmosis311 did you try TitleView?

they are difference things @Shaboo

@minaairsupport
Copy link

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

@samhouts samhouts moved this from Ready for Implementation to Needs Design Review in Enhancements Feb 7, 2019
@smartprogrammer93
Copy link

Any Idea if this will be implemented?

@LuoyeAn
Copy link
Contributor

LuoyeAn commented Jul 10, 2019

Any luck?

@decv86
Copy link

decv86 commented Aug 29, 2019

Pls implementation!

1 similar comment
@decv86
Copy link

decv86 commented Aug 29, 2019

Pls implementation!

@YZahringer
Copy link
Contributor

I think UWP should also be supported: https://www.rudyhuyn.com/blog/2015/12/23/display-an-appbarbutton-on-the-left-side-of-a-commandbar/

@samhouts samhouts moved this from Needs Design Review to Needs Specification in Enhancements Feb 12, 2020
@samhouts samhouts moved this from Needs Design Review to Under consideration-High Interest in Enhancements Feb 12, 2020
@winterdouglas
Copy link

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

@jfversluis
Copy link
Member

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.

@dionisoliveira
Copy link

dionisoliveira commented Apr 2, 2020

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;
        }
    }

  


}

@jfversluis
Copy link
Member

Hey everyone, thanks for all the input and effort here. This won't be able to make it into Xamarin.Forms anymore unfortunately. If it's something you're still interested in, make sure to see if it's on the roadmap for .NET MAUI or open an issue with a feature request and add all the details.

Thanks!

Enhancements automation moved this from Under consideration-High Interest to Closed Nov 4, 2021
@mackayn
Copy link

mackayn commented Nov 4, 2021

@jfversluis Given up on the native toolbar renderer completely. It's only useful for basic scenarios. On the last 4 commercials apps I've been involved with, we rolled out own toolbar as it was the way we could realize the designs. Allowing drawing like Flutter is the way to go.

@jfversluis
Copy link
Member

Thanks @mackayn! That seems definitely be the thing holding us back here and something we're keeping in mind.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Enhancements
  
Closed
Development

No branches or pull requests