0

I have been trying to set the gravity / positioning options for the top tab/toolbar (the layout that appears when you set two ShellContents to a Tab). This has worked on Android, as the Android Shell renderer exposes both CreateBottomNavViewAppearanceTracker and CreateTabLayoutAppearanceTracker.

However, the iOS Shell renderer only exposes CreateTabBarAppearanceTracker in regards to tabs which only deals with (at least from what I understand) the bottom tab (higher hierarchically than ShellContent tabs).

I have tried to subclass ShellItemRenderer, but I couldn't find any properties related to what I wanted.

How it appears on Android:

Appearance of top tab bar on Android

DaddyProphet
  • 128
  • 2
  • 8
  • can you put in some codes? – Visual Sharp Aug 01 '20 at 11:45
  • @VisualSharp What exactly do you want to see? I'm simply asking what renderer, appearance tracker or property / methods I need to use to access customisation for the top tabs. – DaddyProphet Aug 02 '20 at 09:25
  • @DaddyProphet Hi , it seems can not get the top toolbar from `CreateTabBarAppearanceTracker` easily, I will check that in iOS how to achieve that . If good news will update here later. :-) – Junior Jiang Aug 03 '20 at 06:14
  • @DaddyProphet Hi , I have found the solution and updated in answer, you can have a look at that when you have time. :-) – Junior Jiang Aug 06 '20 at 03:10

1 Answers1

1

I have found the solution to access the the top tab/toolbar for iOS on Shell pages. You need a subclass of ShellSectionRootHeader, which is itself a subclass of UICollectionViewController which is the native type that renders the top tab bar on iOS. Once you have that subclass, you can then override the GetCell method to get each individual item in the top tab bar and modify them. But in order to get to that point, you need to subclass and instantiate 2 more renderers beyond the ShellRenderer.

Here is the sample Renderer code in iOS :

[assembly: ExportRenderer(typeof(Shell), typeof(CustomShellRenderer))]
namespace Xaminals.iOS
{
    public class CustomShellRenderer: ShellRenderer
    {
        protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
        {
            var shellSectionRenderer = new CustomShellSectionRenderer(this);
            return shellSectionRenderer;
        }
    }
    public class CustomShellSectionRenderer : ShellSectionRenderer
    {

        public CustomShellSectionRenderer(IShellContext context) : base(context)
        { }

        protected override IShellSectionRootRenderer CreateShellSectionRootRenderer(ShellSection shellSection, IShellContext shellContext)
        {
            var renderer = new CustomShellSectionRootRenderer(shellSection, shellContext);

            return renderer;
        }
    }

    public class CustomShellSectionRootRenderer : ShellSectionRootRenderer
    {
        public CustomShellSectionRootRenderer(ShellSection section, IShellContext context) : base(section, context)
        { }

        protected override IShellSectionRootHeader CreateShellSectionRootHeader(IShellContext shellContext)
        {
            var renderer = new CustomShellSectionRootHeader(shellContext);
            return renderer;
        }
    }

    public class CustomShellSectionRootHeader : ShellSectionRootHeader
    {
        public CustomShellSectionRootHeader(IShellContext context) : base(context)
        {
            
        }

        public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cell = base.GetCell(collectionView, indexPath) as ShellSectionHeaderCell;

            // Set desired font here 
            //cell.Label.Font = UIFont.ItalicSystemFontOfSize(11);

            var layout = new UICollectionViewFlowLayout();
            layout.MinimumInteritemSpacing = UIScreen.MainScreen.Bounds.Size.Width / 8;
            layout.SectionInset = new UIEdgeInsets(top: 0, left: UIScreen.MainScreen.Bounds.Size.Width/4, bottom: 0, right: 0);

            collectionView.CollectionViewLayout = layout;

            return cell;
        }
    }

    public class CustomUICollectionViewFlowLayout : UICollectionViewFlowLayout
    {
        public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect)
        {
            return base.LayoutAttributesForElementsInRect(rect);

        }

    }
}

The effect:

enter image description here

Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
  • I am wondering if this answer could possibly help to resolve https://stackoverflow.com/questions/64397674/append-a-control-above-upper-to-the-shell-app-bar-without-altering-it – Cfun Dec 10 '20 at 12:37
  • @Cfun Hi, I think you could have a try with custom ShellRenderer to modify the Toolbar. Not sure whether it works, but this should be the correct direction to do. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/customrenderers#android-example – Junior Jiang Dec 11 '20 at 03:05
  • Thank you for your reply, Already tried several things with custom renderer in the past without sucess, lately came to know that the ToolBar stack elements horizontal (so whatever I add will be beside other elemnts not above) while the appbar (parent of toolbar) stacks them vertically, I have no idea how to customize the appbar even searched here and there. – Cfun Dec 11 '20 at 03:05
  • 1
    @Cfun I think it's not easy to achieve that in Shell. If you are not using Shell, you could custom a `NavigationRenderer` to moidfy the `Toolbar.xml` in native android. Now I have no idea about Shell Renderer. – Junior Jiang Dec 11 '20 at 03:18