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仅提供左侧滑动功能。
希望有道理!
答案 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"},
};
}