3

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

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

  • 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

  • A screenshot I took from one of my Apps that implements this effect
Kyll
  • 7,036
  • 7
  • 41
  • 64
Daniel
  • 447
  • 5
  • 22

1 Answers1

2

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.

Ax1le
  • 6,563
  • 2
  • 14
  • 61
  • Hello, thank you so much for this response! I am self-taught and new to Xamarin, so please do excuse me if I sound ignorant. How would I go about "creat[ing] a page renderer to display the UIPopoverController". I have followed the guides here, and have managed to make custom Renderers before using the examples that they have provided, but I cannot figure out how I would achieve the above mentioned. Just want to say thanks again for taking the time to write this answer, I really do appreciate it :) – Daniel Jan 08 '18 at 12:47
  • When I said "here", I meant to add this link https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/contentpage/ – Daniel Jan 08 '18 at 12:58
  • @Bracefor If you have managed to create a custom renderer, you can put my code above in the renderer. When you navigate to this page in forms. You can see the effect you want to achieve. – Ax1le Jan 08 '18 at 13:06
  • Okay, so could you maybe tell me then what files I should have where (the name of the file and in which folder it should be) Just to make sure I am doing it right? – Daniel Jan 08 '18 at 13:10
  • @Bracefor the renderer is created at corresponding platform's project. One way you can check whether you are doing right is that override the `OnElementChanged` in the renderer file, then make a break point in this method. If project runs into this method, it means you have successfully made the renderer. – Ax1le Jan 08 '18 at 13:21
  • Yes, but I do not know what files to create where, and I do not fully understand the tutorial I mentioned above. @Land – Daniel Jan 08 '18 at 13:27
  • @Bracefor I think you can read this documentation more carefully. And you can also download the sample, then run it to see which file should be created in which project. I think this will be more useful, because I don't know which file you metioned. please pay more attention to the attribute:`[assembly:ExportRenderer (typeof(CameraPage), typeof(CameraPageRenderer))]` – Ax1le Jan 08 '18 at 13:37