Xamarin表示ViewCell滑动以显示按钮

时间:2016-04-11 22:37:03

标签: ios xamarin xamarin.ios xamarin.forms swipe-gesture

tl; dr:如何使用滑动来显示Xamarin Forms中的按钮,如iOS邮件应用

我正在尝试为类似于iOS邮件应用或此https://components.xamarin.com/view/swtableviewcell的用户界面的Xamarin Forms iOS应用实施滑动以显示按钮。在我发现的许多其他示例中,该组件看起来非常适合iOS本机实现,但我需要通过Xamarin表单显示此UI。

目前我有一个自定义滑动手势识别器,如下所示:

    [assembly: ExportRenderer(typeof(SwipeViewCell), typeof(SwipeIosRenderer))]

namespace MyApp.iOS.Renderers
   {
    public class SwipeIosRenderer : ViewCellRenderer
       {


    UISwipeGestureRecognizer swipeRightGestureRecognizer;
    UISwipeGestureRecognizer swipeLeftGestureRecognizer;

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);


        swipeRightGestureRecognizer = new UISwipeGestureRecognizer(() => UpdateRight()) { Direction = UISwipeGestureRecognizerDirection.Right };
        swipeLeftGestureRecognizer = new UISwipeGestureRecognizer(() => UpdateLeft()) { Direction = UISwipeGestureRecognizerDirection.Left };

        if (e.NewElement == null)
        {

            if (swipeRightGestureRecognizer != null)
            {
                this.RemoveGestureRecognizer(swipeRightGestureRecognizer);
            }
            if (swipeLeftGestureRecognizer != null)
            {
                this.RemoveGestureRecognizer(swipeLeftGestureRecognizer);
            }
        }

        if (e.OldElement == null)
        {

            this.AddGestureRecognizer(swipeRightGestureRecognizer);
            this.AddGestureRecognizer(swipeLeftGestureRecognizer);                
        }

    }

    private void UpdateLeft()
    {

        Console.WriteLine("Left swipe");

    }
    private void UpdateRight()
    {

        Console.WriteLine("Right swipe");

    }
}

这与列表中的viewcells绑定。现在我可以识别“滑动”手势,我需要帮助,如何实际移动视图单元格并显示一个按钮,就像我上面给出的示例一样?

能够在XAML视图中执行此操作会很棒,但我可以接受任何操作。我有一个UpdateLeft和UpdateRight函数,如果可以使用它也可以在相应的滑动动作上调用?

**编辑:我需要为左右滑动执行此操作。 ContextActions仅提供左侧滑动功能。

希望有道理!

1 个答案:

答案 0 :(得分:5)

Context Actions会为你效劳吗?我没有尝试过其他平台,但在iOS上它会像Mail应用程序一样创建一个滑动菜单。您应该能够使用XAML并绑定到命令属性。

修改 由于您澄清了需要ContextActions中不存在的左侧和右侧滑动按钮,因此您可以利用已具有所需行为的现有SWTableViewCell组件并将其调整为Xamarin.Forms。

<强> iOSRenderer:

public class SwipeIosRenderer : TextCellRenderer
{

static NSString rid = new NSString("SWTableViewCell");

public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
    var forms_cell = (SwipeCell)item;

    SWTableViewCell native_cell = reusableCell as SWTableViewCell;
    if (native_cell == null)
    {
        native_cell = new SWTableViewCell(UITableViewCellStyle.Default, rid);

        if (forms_cell != null)
        {
            var cellDelegate = new CellDelegate(forms_cell);
            native_cell.Delegate = cellDelegate;

            if (forms_cell.LeftContextActions != null)
            {
                var left = new NSMutableArray();
                foreach (var btn in forms_cell.LeftContextActions)
                {
                    AddButton(left, btn);
                }
                native_cell.LeftUtilityButtons = NSArray.FromArray<UIButton>(left);
            }

            if (forms_cell.RightContextActions != null)
            {
                var right = new NSMutableArray();
                foreach (var btn in forms_cell.RightContextActions)
                {
                    AddButton(right, btn);
                }
                native_cell.RightUtilityButtons = NSArray.FromArray<UIButton>(right);
                }
            }
            native_cell.TextLabel.Text = forms_cell.Text;
    }
    var fs = forms_cell.ImageSource as FileImageSource;
    if (fs != null)
    {
        native_cell.ImageView.Image = UIImage.FromBundle(fs.File);
    }
    return native_cell;
}
void AddButton(NSMutableArray array,Button btn){
    if (!String.IsNullOrEmpty(btn.Image?.File))
    {
        array.AddUtilityButton(btn.BorderColor.ToUIColor(), UIImage.FromBundle(btn.Image.File));
    }
    else
    {
        array.AddUtilityButton(btn.BorderColor.ToUIColor(), btn.Text);
    }
}

public class CellDelegate : SWTableViewCellDelegate
{
    SwipeCell forms_cell;

    public CellDelegate(SwipeCell forms_cell)
    {
        this.forms_cell = forms_cell;
    }

    public override void DidTriggerLeftUtilityButton(SWTableViewCell cell, nint index)
    {
        if (forms_cell.LeftContextActions.Count > index)
        {
            var c = forms_cell.LeftContextActions[(int)index];
            var cmd = c.Command;
            if (cmd != null)
            {
                cmd.Execute(c.CommandParameter);
            }
        }
    }

    public override void DidTriggerRightUtilityButton(SWTableViewCell cell, nint index)
    {
        if (forms_cell.RightContextActions.Count > index)
        {
            var c = forms_cell.RightContextActions[(int)index];
            var cmd = c.Command;
            if (cmd != null)
            {
                cmd.Execute(c.CommandParameter);
            }
        }
    }
}

示例XAML:

<ListView x:Name="SwipeList">
        <ListView.ItemTemplate>
            <DataTemplate>

            <test:SwipeCell Text="{Binding Data}" ImageSource="{Binding Image}">
                    <test:SwipeViewCell.LeftContextActions>
                        <Button Text="L1" Command="{Binding LeftAction}" BorderColor="Aqua"/>
                        <Button Command="{Binding LeftAction2}" BorderColor="Gray" Image="xamarin.png"/>
                    </test:SwipeViewCell.LeftContextActions>
                    <test:SwipeViewCell.RightContextActions>
                        <Button Text="R1" Command="{Binding RightAction}" BorderColor="Blue" />
                        <Button Text="R2" Command="{Binding RightAction2}" BorderColor="Purple" />
                    </test:SwipeViewCell.RightContextActions>
                </test:SwipeViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

背后的示例代码

public class MyListItem
{
    Page page;
    public MyListItem(Page page)
    {
        this.page = page;
        this.LeftAction= new Command(() => this.page.DisplayAlert("Left 1", this.Data, "OK"));
        this.LeftAction2= new Command(() => this.page.DisplayAlert("Left 2", this.Data, "OK"));
        this.RightAction= new Command(() => this.page.DisplayAlert("Right 1", this.Data, "OK"));
        this.RightAction2= new Command(() => this.page.DisplayAlert("Right 2", this.Data, "OK"));
    }
    public string Image{ get; set; }
    string data;
    public string Data
    {
        get
        {
            return data;
        }
        set
        {
            data = value;
        }
    }
    ICommand leftAction;
    public ICommand LeftAction
    {
        get
        {
            return leftAction;
        }
        set
        {
            leftAction = value;
        }
    }
    ICommand leftAction2;
    public ICommand LeftAction2
    {
        get
        {
            return leftAction2;
        }
        set
        {
            leftAction2 = value;
        }
    }
    ICommand rightAction;
    public ICommand RightAction
    {
        get
        {
            return rightAction;
        }
        set
        {
            rightAction = value;
        }
    }
    ICommand rightAction2;
    public ICommand RightAction2
    {
        get
        {
            return rightAction2;
        }
        set
        {
            rightAction2 = value;
        }
    }
    public override string ToString()
    {
        return this.Data;
    }
    }
    public TestPage()
    {
        InitializeComponent();
        this.SwipeList.ItemsSource = new List<MyListItem>(){
            new MyListItem(this){Data="A"},
            new MyListItem(this){Data="B", Image="xamarin.png"},
            new MyListItem(this){Data="C"},
            new MyListItem(this){Data="D"},
        };
    }