Xamarin.forms 辅助工具栏项不适合屏幕

Xamarin.forms 辅助工具栏项不适合屏幕,xamarin.forms,xamarin.ios,Xamarin.forms,Xamarin.ios,我有一个带有FreshMvvm的Xamarin.Forms应用程序,我使用辅助工具栏项。要在iOS中实现这一点,我必须制作一个定制的渲染器(与Android不同)。我在这里得到了如何实施的解决方案: 这个解决方案对我非常有效。但现在,工具栏菜单变长了,它的一些元素不适合iPhone的屏幕。我可以滑动菜单并查看所有元素,但只要我松开屏幕,视图就会跳起来,当它被手指握住时,元素就无法单击。如何解决这个问题?可以把菜单包起来吗,或者别的什么? 在Android上,菜单停留在我滚动的地方,我可以点击每

我有一个带有FreshMvvm的Xamarin.Forms应用程序,我使用辅助工具栏项。要在iOS中实现这一点,我必须制作一个定制的渲染器(与Android不同)。我在这里得到了如何实施的解决方案:

这个解决方案对我非常有效。但现在,工具栏菜单变长了,它的一些元素不适合iPhone的屏幕。我可以滑动菜单并查看所有元素,但只要我松开屏幕,视图就会跳起来,当它被手指握住时,元素就无法单击。如何解决这个问题?可以把菜单包起来吗,或者别的什么? 在Android上,菜单停留在我滚动的地方,我可以点击每一项。它也能在iOS上滚动吗

以下是我的渲染器代码:

using CoreGraphics;
using MobileApp.iOS.Renderers;
using MobileApp.iOS.Services;
using MobileApp.Pages;
using MobileApp.Services;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CustomToolbarContentPage), 
typeof(RightToolbarMenuCustomRenderer))]
namespace MobileApp.iOS.Renderers
{
class RightToolbarMenuCustomRenderer : PageRenderer
{
    private List<ToolbarItem> _primaryItems;
    private List<ToolbarItem> _secondaryItems;
    private UITableView _table;
    private UITapGestureRecognizer _tapGestureRecognizer;
    private UIView _transparentView;

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        if (e.NewElement is IAddToolbarItem item)
        {
            item.ToolbarItemAdded += Item_ToolbarItemAdded;
        }
        base.OnElementChanged(e);
    }

    private void Item_ToolbarItemAdded(object sender, System.EventArgs e)
    {
        if (Element is ContentPage page)
        {
            _primaryItems = page.ToolbarItems.Where(i => i.Order == ToolbarItemOrder.Primary).ToList();
            _secondaryItems = page.ToolbarItems.Where(i => i.Order == ToolbarItemOrder.Secondary).ToList();
            _secondaryItems.ForEach(t => page.ToolbarItems.Remove(t));
        }

        var element = (ContentPage)Element;

        if (_secondaryItems?.Count == 0 && element.ToolbarItems.Any(a => (a.IconImageSource as FileImageSource)?.File == "more.png"))
        {
            element.ToolbarItems.Clear();
        }
        else if (_secondaryItems?.Count >= 1 && !element.ToolbarItems.Any(a => (a.IconImageSource as FileImageSource)?.File == "more.png"))
        {
            element.ToolbarItems.Add(new ToolbarItem()
            {
                Order = ToolbarItemOrder.Primary,
                IconImageSource = "more.png",
                Priority = 1,
                Command = new Command(ToggleDropDownMenuVisibility)
            });
        }
    }

    private void ToggleDropDownMenuVisibility()
    {
        if (!DoesTableExist())
        {
            if ((View?.Subviews != null)
                && (View.Subviews.Length > 0)
                && (View.Bounds != null)
                && (_secondaryItems != null)
                && (_secondaryItems.Count > 0))
            {
                _table = OpenDropDownMenu(Element as IAddToolbarItem);
                Add(_table);
            }
        }
        else
            CloseDropDownMenu();
    }

    private bool DoesTableExist()
    {
        if (View?.Subviews != null)
        {
            foreach (var subview in View.Subviews)
            {
                if (_table != null && subview == _table)
                {
                    return true;
                }
            }
        }
        if (_tapGestureRecognizer != null)
        {
            _transparentView?.RemoveGestureRecognizer(_tapGestureRecognizer);
            _tapGestureRecognizer = null;
        }
        _table = null;
        _tapGestureRecognizer = null;
        return false;
    }

    private UITableView OpenDropDownMenu(IAddToolbarItem secondaryMenuSupport)
    {
        _transparentView = _transparentView = new UIView(new CGRect(0, 0, View.Bounds.Width, View.Bounds.Height))
        {
            BackgroundColor = UIColor.FromRGBA(0, 0, 0, 0)
        };
        _tapGestureRecognizer = new UITapGestureRecognizer(CloseDropDownMenu);
        _transparentView.AddGestureRecognizer(_tapGestureRecognizer);
        Add(_transparentView);

        UITableView table = null;
        if (_secondaryItems != null && _secondaryItems.Count > 0)
        {
            table = new UITableView(GetPositionForDropDownMenu(secondaryMenuSupport.RowHeight, secondaryMenuSupport.TableWidth))
            {
                Source = new TableSource(_secondaryItems, _transparentView),
                ClipsToBounds = false
            };

            table.ScrollEnabled = true;
            table.Layer.ShadowColor = secondaryMenuSupport.ShadowColor.ToCGColor();
            table.Layer.ShadowOpacity = secondaryMenuSupport.ShadowOpacity;
            table.Layer.ShadowRadius = secondaryMenuSupport.ShadowRadius;
            table.Layer.ShadowOffset = new SizeF(secondaryMenuSupport.ShadowOffsetDimension, secondaryMenuSupport.ShadowOffsetDimension);
            table.BackgroundColor = secondaryMenuSupport.MenuBackgroundColor.ToUIColor();
        }
        return table;
    }

    public override void ViewWillDisappear(bool animated)
    {
        CloseDropDownMenu();
        base.ViewWillDisappear(animated);
    }

    private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
    {
        if ((View?.Bounds != null)
            && (_secondaryItems != null)
            && (_secondaryItems.Count > 0))
        {
            return new RectangleF(
                (float)View.Bounds.Width - tableWidth,
                0,
                tableWidth,
                _secondaryItems.Count() * rowHeight);
        }
        else
        {
            return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
        }
    }

    private void CloseDropDownMenu()
    {
        if (_table != null)
        {
            if (_tapGestureRecognizer != null)
            {
                _transparentView?.RemoveGestureRecognizer(_tapGestureRecognizer);
                _tapGestureRecognizer = null;
            }

            if (View?.Subviews != null)
            {
                foreach (var subview in View.Subviews)
                {
                    if (subview == _table)
                    {
                        _table.RemoveFromSuperview();
                        break;
                    }
                }

                if (_transparentView != null)
                {
                    foreach (var subview in View.Subviews)
                    {
                        if (subview == _transparentView)
                        {
                            _transparentView.RemoveFromSuperview();
                            break;
                        }
                    }
                }
            }
            _table = null;
            _transparentView = null;
        }
    }

    public override void ViewDidLayoutSubviews()
    {
        base.ViewDidLayoutSubviews();

        if (_table != null)
        {
            if (Element is IAddToolbarItem secondaryMenuSupport)
                PositionExistingDropDownMenu(secondaryMenuSupport.RowHeight, secondaryMenuSupport.TableWidth);
        }
    }

    private void PositionExistingDropDownMenu(float rowHeight, float tableWidth)
    {
        if ((View?.Bounds != null)
            && (_secondaryItems != null)
            && (_secondaryItems.Count > 0)
            && (_table != null))
        {
            _table.Frame = GetPositionForDropDownMenu(rowHeight, tableWidth);
        }
    }
}
}
使用CoreGraphics;
使用MobileApp.iOS.Renderers;
使用MobileApp.iOS.Services;
使用MobileApp.页面;
使用MobileApp.服务;
使用System.Collections.Generic;
使用系统图;
使用System.Linq;
使用UIKit;
使用Xamarin.Forms;
使用Xamarin.Forms.Platform.iOS;
[程序集:ExportRenderer(typeof(CustomToolbarContentPage)),
typeof(RightToolbarMenuCustomRenderer))]
命名空间MobileApp.iOS.Renderers
{
类RightToolbarMenuCustomRenderer:PageRenderer
{
私有列表(primaryItems);
私人清单(二级项目),;
私有UITableView_表;
专用UITapGestureRecognitor\u TapGestureRecognitor;
私人UIView(透明视图);
受保护的覆盖无效OnElementChanged(VisualElementChangedEventArgs e)
{
如果(例如,新元素是IAddToolbarItem项)
{
item.ToolbarItemAdded+=item_ToolbarItemAdded;
}
基础。一个要素发生变化(e);
}
已添加私有无效项(对象发送方,System.EventArgs e)
{
if(元素为ContentPage)
{
_primaryItems=page.ToolbarItems.Where(i=>i.Order==ToolbarItemOrder.Primary.ToList();
_secondaryItems=page.ToolbarItems.Where(i=>i.Order==ToolbarItemOrder.Secondary.ToList();
_ForEach(t=>page.ToolbarItems.Remove(t));
}
var元素=(ContentPage)元素;
if(_secondaryItems?.Count==0&&element.ToolbarItems.Any(a=>(a.IconImageSource作为FileImageSource)?.File==“more.png”))
{
element.ToolbarItems.Clear();
}
如果(_secondaryItems?.Count>=1&&!element.ToolbarItems.Any(a=>(a.IconImageSource作为FileImageSource)?.File==“more.png”))
{
元素.ToolbarItems.Add(新的ToolbarItem()
{
Order=ToolbarItemOrder.Primary,
IconImageSource=“more.png”,
优先级=1,
命令=新命令(切换下拉菜单可见性)
});
}
}
私有无效切换DropDownMenuVisibility()
{
如果(!DoesTableExist())
{
if((视图?.Subviews!=null)
&&(View.Subviews.Length>0)
&&(View.Bounds!=null)
&&(_secondaryItems!=null)
&&(_secondaryItems.Count>0))
{
_表=OpenDropDownMenu(元素为IAddToolbarItem);
添加(_表);
}
}
其他的
关闭下拉菜单();
}
二等兵布尔·多斯塔布利克斯特()
{
if(视图?.Subviews!=null)
{
foreach(视图中的var子视图。子视图)
{
if(_table!=null&&subview==_table)
{
返回true;
}
}
}
if(_-tapGestureRecognizer!=null)
{
_transparentView?.RemoveTestureRecognizer(_tapGestureRecognizer);
_tapGestureRecognizer=null;
}
_table=null;
_tapGestureRecognizer=null;
返回false;
}
专用UITableView打开下拉菜单(IAddToolbarItem第二菜单支持)
{
_transparentView=\u transparentView=新的UIView(新的CGRect(0,0,View.Bounds.Width,View.Bounds.Height))
{
BackgroundColor=UIColor.FromRGBA(0,0,0,0)
};
_tapGestureRecognizer=新建UITapGestureRecognizer(关闭下拉菜单);
_transparentView.AddGestureRecognizer(_tapGestureRecognizer);
添加(_transparentView);
UITableView表=空;
if(_secondaryItems!=null&&u secondaryItems.Count>0)
{
table=new UITableView(GetPositionForDropDownMenu(secondaryMenuSupport.RowHeight,secondaryMenuSupport.TableWidth))
{
Source=新表源(_secondaryItems,_transparentView),
ClipsToBounds=false
};
table.ScrollEnabled=true;
table.Layer.ShadowColor=secondaryMenuSupport.ShadowColor.togcolor();
table.Layer.ShadowOpacity=secondaryMenuSupport.ShadowOpacity;
table.Layer.ShadowRadius=secondaryMenuSupport.ShadowRadius;
table.Layer.ShadowOffset=new SizeF(secondaryMenuSupport.ShadowOffsetDimension,secondaryMenuSupport.ShadowOffsetDimension);
table.BackgroundColor=secondaryMenuSupport.MenuBackgroundColor.ToUIColor();
}
返回表;
}
公共覆盖无效视图将消失(布尔动画)
{
关闭下拉菜单();
基本视图将消失(动画);
}
私有矩形F GetPositionForDropDownMenu(浮动行高、浮动表宽)
{
if((视图?.Bounds!=null)
&&(_secondaryItems!=null)
&&(_secondaryItems.Count>0))
{
返回新矩形F(
(float)View.Bounds.Width-tableWidth,
0,
桌宽,
_secondary items.Count()*行高);
}
其他的
{
返回新矩形F(0.0f,0.0f,0.0f,0.0f);
}
}
私有无效关闭下拉菜单()
{
如果(_)选项卡
public class TableSource : UITableViewSource
{
    List<ToolbarItem> _tableItems;
    string[] _tableItemTexts;
    string CellIdentifier = "TableCell";
    UIView _tableSuperView = null;

    public TableSource(List<ToolbarItem> items, UIView tableSuperView)
    {
        _tableItems = items;
        _tableSuperView = tableSuperView;
        _tableItemTexts = items.Select(a => a.Text).ToArray();
    }

    public override nint RowsInSection(UITableView tableview, nint section)
    {
        return _tableItemTexts?.Length ?? 0;
    }

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
        string item = _tableItemTexts[indexPath.Row];
        if (cell == null)
        { cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); }
        cell.TextLabel.Text = item;
        return cell;
    }

    public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
    {
        return 56;
    }

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        var command = _tableItems[indexPath.Row].Command;
        command.Execute(_tableItems[indexPath.Row].CommandParameter);
        tableView.DeselectRow(indexPath, true);
        tableView.RemoveFromSuperview();
        if (_tableSuperView != null)
        {
            _tableSuperView.RemoveFromSuperview();
        }
    }
}

public interface IAddToolbarItem
{
    event EventHandler ToolbarItemAdded;
    Color CellBackgroundColor { get; }
    Color CellTextColor { get; }
    Color MenuBackgroundColor { get; }
    float RowHeight { get; }
    Color ShadowColor { get; }
    float ShadowOpacity { get; }
    float ShadowRadius { get; }
    float ShadowOffsetDimension { get; }
    float TableWidth { get; }
}
 _table = OpenDropDownMenu(Element as IAddToolbarItem);
 Add(_table);
  _table = OpenDropDownMenu(Element as IAddToolbarItem);
  //Add(_table);
  _transparentView.Add(_table);
private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
{
    if ((View?.Bounds != null)
        && (_secondaryItems != null)
        && (_secondaryItems.Count > 0))
    {
        return new RectangleF(
            (float)View.Bounds.Width - tableWidth,
            0,
            tableWidth,

            //here is the cause
            _secondaryItems.Count() * rowHeight);
    }
    else
    {
        return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
    }
}
private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
{
    if ((View?.Bounds != null)
        && (_secondaryItems != null)
        && (_secondaryItems.Count > 0))
    {
        return new RectangleF(
            (float)View.Bounds.Width - tableWidth,
            0,
            tableWidth,
            (float)View.Bounds.Height);
    }
    else
    {
        return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
    }
}