androidiosxamarinxamarin.formstoolbaritems

Replicating the drop-down ToolbarItem "More" in Xamarin.Forms


I am struggling how I could replicate the drop-down ToolbarItem from Xamarin.Forms when a ToolbarItem's order is set to Secondary for IOS, in order for it to look like it does for Android.


Here are some images to better explain what I am looking for:

How it works on Android:

  1. Code:
ToolbarItem toolbarItem = new ToolbarItem()
{
  Text = "ToolbarItem",
  Order = ToolbarItemOrder.Secondary
};
  1. Images on how it looks on Android:

Image showing the "More" icon

Image showing the "More" icon expanded to show more toolbar items

There is no default "More" icon on the toolbar when setting the Order to Secondary in iOS. Instead what happens, is that a bar below the navigation bar is created, which includes all of the toolbar items - something I do not wish to have for my Application.


This is an example of how it has been achieved before on IOS:

A screenshot I took from one of my Apps that implements this effect


Solution

  • In native iOS, you can use UIPopoverController to achieve your effect. But please notice that this control can only be used in iPad.

    Since you are using Xamarin.Forms, we can create a custom renderer in iOS platform to get this.

    Firstly, create a page renderer to display the UIPopoverController. We can show it from a UIBarButtonItem or a UIView depending on your request. Here I use UIBarButtonItem like:

    //I defined the navigateItem in the method ViewWillAppear
    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
    
        rightItem = new UIBarButtonItem("More", UIBarButtonItemStyle.Plain, (sender, args) =>
        {
            UIPopoverController popView = new UIPopoverController(new ContentViewController());
            popView.PopoverContentSize = new CGSize(200, 300);
            popView.PresentFromBarButtonItem(rightItem, UIPopoverArrowDirection.Any, true);
        });
    
        NavigationController.TopViewController.NavigationItem.SetRightBarButtonItem(leftItem, true);
    }
    

    Secondly, construct the content ViewController in the UIPopoverController(just like the secondary list in android):

    public class ContentViewController : UIViewController
    {
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
    
            UITableView tableView = new UITableView(new CGRect(0, 0, 200, 300));
            tableView.Source = new MyTableViewSource();
            View.AddSubview(tableView);
        }
    }
    
    public class MyTableViewSource : UITableViewSource
    {
        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            UITableViewCell cell = tableView.DequeueReusableCell(new NSString("Cell"));
            if (cell == null)
            {
                cell = new UITableViewCell(UITableViewCellStyle.Default, new NSString("Cell"));
            }
    
            cell.TextLabel.Text = "Item" + indexPath.Row;
    
            return cell;
        }
    
        public override nint RowsInSection(UITableView tableview, nint section)
        {
            return 10;
        }
    }
    

    At last we can show it on the screen by calling PresentFromBarButtonItem.