ToolBarItems Left side

rmarinhormarinho PTMember, Insider, Beta Xamurai

Is it possible to specify toolbar button items to go to the left side ?

«1

Posts

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    no, not right now

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    :)

  • alxbogalxbog RUMember ✭✭

    Important issue for iOS. For example, it's impossible now to implement commonly used Save/Cancel modal views.

  • alxbogalxbog RUMember ✭✭

    It would be possible to workaround this issue if we find a way to override ToolbarRenderer.
    Created a separate question here: http://forums.xamarin.com/discussion/20467/how-to-override-toolbarrenderer

  • MichaelRidlandMichaelRidland AUInsider, University ✭✭✭

    @StephaneDelcroix‌ @rene_ruppert‌ bump on this one.

    Has this been fixed?
    Or has the ability to override been fixed?

    This a basic requirement for pretty much every mobile application in iOS.

  • chris_riesgochris_riesgo USUniversity ✭✭✭

    It's not pretty, but I showed my approach on another thread.

  • MichaelRidlandMichaelRidland AUInsider, University ✭✭✭

    Update: If you follow Angel Anton Yebra instructions on this page you can work around the issue: http://forums.xamarin.com/discussion/20467/how-to-override-toolbarrenderer

  • JoeBoothJoeBooth USMember ✭✭

    +1

  • BrunoVTBrunoVT BEUniversity ✭✭

    +1

  • rogiheerogihee NLMember ✭✭✭

    +1

  • MihaMarkicMihaMarkic SI ✭✭✭✭

    It'd be nice if Forms were a little bit more open to let handle these "exotic" requirements by ourselves.

  • OliverMaderOliverMader USMember

    +1 Has this been solved recently?

  • OSDMobileOSDMobile NLUniversity ✭✭
    edited May 2015

    Currently when you add toolbar items, the first one will be rendered on the left side for iOS.

    You can customize the behavior using a custom renderer. In this case a NavigationRenderer.

  • OliverMaderOliverMader USMember

    This doesn't seem to apply for ToolbarItems set through XAML.

  • JeffButterworthJeffButterworth AUMember ✭✭

    @AndreiNitescu I did see that thread. It's been a very long few days trying to get an app framework together. I guess I am a bit over having to dig deep into ugly hacks everytime I turn around to do something new. At this stage I am ending up with a working app but damn its ugly. At some stage I will need to go through all these hacks to get something that looks decent but focusing on getting something working right now.

  • AndrewMobileAndrewMobile USMember ✭✭✭✭
    edited June 2015

    @JeffButterworth I have same issues, I share your pain. I wanted to help by making sure everyone's on this thread sees that "workaround".

  • Has this been solved in the latest release?

  • n.kuznetsovn.kuznetsov USUniversity ✭✭

    up

  • ClmentNonn.8916ClmentNonn.8916 USMember

    up

  • AlexanderFaulandAlexanderFauland USMember ✭✭

    Any changes here?

  • David_PilkingtonDavid_Pilkington USUniversity

    Would be nice if this was updated.

  • MeikeHammerMeikeHammer USMember

    +1

  • Abhijeet_SuryaAbhijeet_Surya USMember ✭✭✭

    +1000000

  • LushLush USMember ✭✭

    Hey guys,

    The left toolbar item makes sense only in iOS. There is no left button in Android. So basically you need a collection in the base page like LeftToolbarItems that will add a ToolbarItem in the left on iOS only:

        public class BasePage: ContentPage
            {
                public ObservableCollection<ToolbarItem> LeftToolbarItems { get; set; }
    
                public BasePage()
                {
                    LeftToolbarItems = new ObservableCollection<ToolbarItem>();
                }
            }
    

    All you need now is the renderer in the iOS. Pierce Boggan from Xamarin has implemented this very elegantly HERE.

    To use it in Xamarin.Forms:

    var cancelItem = new ToolbarItem();
    
    if (Device.OS != TargetPlatform.iOS)
    {
        ToolbarItems.Add(cancelItem);
    }
    else
    {
        LeftToolbarItems.Add(cancelItem);
    }
    
  • WerckAyrtonWerckAyrton FRUniversity ✭✭

    I disagree with you, look at google application on Android (inbox for example) you will see button on the navbar on the left side.

    We are in 2016 and there is still no easy way to do it?

  • NamyslawSzymaniukNamyslawSzymaniuk USMember ✭✭✭✭

    I'd recommend Telerik RadSideDrawer solution:
    http://docs.telerik.com/devtools/xamarin/controls/sidedrawer/sidedrawer-overview

    • custom toolbar.

    Best solution, if you want top toolbar + menu, looking same on each platform.

  • EmanueleSabettaEmanueleSabetta ITBeta ✭✭✭

    Can we just replace the toolbar with a Grid? Is there a way to keep the grid fixed while we navigate the content pages?

  • JohnHardmanJohnHardman GBUniversity mod

    @EmanueleSabetta - That's my plan when I get around to replacing the built-in toolbar.

  • GurpalVirdee.5730GurpalVirdee.5730 USMember
    edited September 2016

    Thanks @Lush, works brilliantly!

  • JassimRahmaJassimRahma USMember ✭✭✭✭

    still no solution form Xamarin?!

  • rene_ruppertrene_ruppert DEXamarin Team, University, XamUProfessors Xamurai

    Xamarin.Forms will never support every possible native feature but it is relatively easy to add support. You could use a custom renderer or create an Effect which does the same.

  • SveinLarsenSveinLarsen NOMember

    I was fiddling with this problem and then suddenly reliazed that ToolbarItem had a function called ToUIBarButtonItem.
    Then based on other posts here we can make a custom renderer that doesnt base itself on existing UIBarButtonItems but just create new ones. I havent tested it with hamburger-menu and stuff like that but it works the same way as the other examples around.

    I just created a general renderer for all my content-pages but you can specify pages-type if you want to changing the first typeof in the ExportRenderer.

    This is for iOS but you can adjust it for andoid too i guess.

    To use it you just use the priority - negative numbers will be on left side and positive on right side.
    Example XAML:

    <ContentPage.ToolbarItems>
        <ToolbarItem Name="Cancel" Priority="-1" Order="Primary" /><!-- Negative goes on the left side -->
        <ToolbarItem Name="Save" Priority="1" Order="Primary" /><!-- Positive priority goes on the right side -->
    </ContentPage.ToolbarItems>
    

    Only thing you have to do is adding this file to your iOS project (you also have to edit the namespace ProjectName to fit your project):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Foundation;
    using UIKit;
    
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(ContentPage), typeof(ProjectName.iOS.CustomContentPageRenderer))]
    
    namespace ProjectName.iOS
    {
        class CustomContentPageRenderer : PageRenderer
        {
            public new ContentPage Element {
                get { return (ContentPage)base.Element; }
            }
    
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
                List<UIBarButtonItem> LeftNavList = new List<UIBarButtonItem>();
                List<UIBarButtonItem> RightNavList = new List<UIBarButtonItem>();
                List<ToolbarItem> ToolbarList = new List<ToolbarItem>();
    
                UINavigationItem navigationItem = this.NavigationController.TopViewController.NavigationItem;
    
                // Add to new list for sorting
                foreach (ToolbarItem itm in Element.ToolbarItems)
                {
                    ToolbarList.Add(itm);
                }
    
                // Sort the list
                ToolbarList.Sort((ToolbarItem i1, ToolbarItem i2) =>
                {
                    return i1.Priority > i2.Priority ? -1 : 1;
                });
    
                foreach (ToolbarItem itm in ToolbarList)
                {
                    if (itm.Priority < 0)
                    {
                        LeftNavList.Add(itm.ToUIBarButtonItem());
                    }
                    else
                    {
                        RightNavList.Add(itm.ToUIBarButtonItem());
                    }
                }
                navigationItem.SetLeftBarButtonItems(LeftNavList.ToArray(), false);
                navigationItem.SetRightBarButtonItems(RightNavList.ToArray(), false);
            }
        }
    }
    

    I am kinda new to Xamarin in general so feedback are welcome :)

  • SveinLarsenSveinLarsen NOMember
    edited December 2017

    (double post deleted)

  • seanydaseanyda GBMember ✭✭✭✭✭

    @SveinLarsen said:
    I was fiddling with this problem and then suddenly reliazed that ToolbarItem had a function called ToUIBarButtonItem.
    Then based on other posts here we can make a custom renderer that doesnt base itself on existing UIBarButtonItems but just create new ones. I havent tested it with hamburger-menu and stuff like that but it works the same way as the other examples around.

    I just created a general renderer for all my content-pages but you can specify pages-type if you want to changing the first typeof in the ExportRenderer.

    This is for iOS but you can adjust it for andoid too i guess.

    To use it you just use the priority - negative numbers will be on left side and positive on right side.
    Example XAML:

    <ContentPage.ToolbarItems>
      <ToolbarItem Name="Cancel" Priority="-1" Order="Primary" />
      <ToolbarItem Name="Save" Priority="1" Order="Primary" />
    </ContentPage.ToolbarItems>
    

    Only thing you have to do is adding this file to your iOS project:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Foundation;
    using UIKit;
    
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(ContentPage), typeof(ProjectName.iOS.CustomContentPageRenderer))]
    
    namespace ProjectName.iOS
    {
      class CustomContentPageRenderer : PageRenderer
      {
          public new ContentPage Element {
              get { return (ContentPage)base.Element; }
          }
    
          public override void ViewWillAppear(bool animated)
          {
              base.ViewWillAppear(animated);
              List<UIBarButtonItem> LeftNavList = new List<UIBarButtonItem>();
              List<UIBarButtonItem> RightNavList = new List<UIBarButtonItem>();
              List<ToolbarItem> ToolbarList = new List<ToolbarItem>();
    
              UINavigationItem navigationItem = this.NavigationController.TopViewController.NavigationItem;
              
              // Add to new list for sorting
              foreach (ToolbarItem itm in Element.ToolbarItems)
              {
                  ToolbarList.Add(itm);
              }
    
              // Sort the list
              ToolbarList.Sort((ToolbarItem i1, ToolbarItem i2) =>
              {
                  return i1.Priority > i2.Priority ? -1 : 1;
              });
    
              foreach (ToolbarItem itm in ToolbarList)
              {
                  if (itm.Priority < 0)
                  {
                      LeftNavList.Add(itm.ToUIBarButtonItem());
                  }
                  else
                  {
                      RightNavList.Add(itm.ToUIBarButtonItem());
                  }
              }
              navigationItem.SetLeftBarButtonItems(LeftNavList.ToArray(), false);
              navigationItem.SetRightBarButtonItems(RightNavList.ToArray(), false);
          }
      }
    }
    

    I am kinda new to Xamarin in general so feedback are welcome :)

    Looks nice, Nice contribution thanks!

  • CodeGrueCodeGrue USMember ✭✭
    edited February 2018

    Since Xamarin may have already added a menu item to the left, as in the case of a master-detail layout, the code below is streamlined and handles this variation keeping the left menu that's already there.

    using System.Linq;
    using UIKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(ContentPage), typeof(ProjectName.iOS.Renderers.CustomContentPageRenderer))]
    namespace ProjectName.iOS.Renderers
    {
        class CustomContentPageRenderer : PageRenderer
        {
            public new ContentPage Element
            {
                get { return (ContentPage)base.Element; }
            }
    
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
    
                ConfigureToolbarItems();
            }
    
            private void ConfigureToolbarItems()
            {
                if (NavigationController != null)
                {
                    UINavigationItem navigationItem = NavigationController.TopViewController.NavigationItem;
                    var orderedItems = Element.ToolbarItems.OrderBy(x => x.Priority);
    
                    // add right side items
                    var rightItems = orderedItems.Where(x => x.Priority >= 0).Select(x => x.ToUIBarButtonItem()).ToArray();
                    navigationItem.SetRightBarButtonItems(rightItems, false);
    
                    // add left side items, keep any already there
                    var leftItems = orderedItems.Where(x => x.Priority < 0).Select(x => x.ToUIBarButtonItem()).ToArray();
                    if (navigationItem.LeftBarButtonItems != null)
                        leftItems = navigationItem.LeftBarButtonItems.Union(leftItems).ToArray();
                    navigationItem.SetLeftBarButtonItems(leftItems, false);
                }          
            }
        }
    }
    
  • raybezraybez Member

    This looks like exactly what I need, but I am brand new to Xamarin Forms and need some guidance on how to customize the code for Android. To start with, how do I need to change it to address the error below?

    PageRenderer.PageRenderer() is obsolete. This constructor is obsolete as of version 2.5. Please use PageRenderer(Context) instead.

Sign In or Register to comment.