Как я могу сделать> в ячейке с Xamarin.Forms?

У меня есть приложение, в котором я могу изменить порядок и способ отображения карт. Для тех, у кого есть iOS, мне нужно что-то очень похожее на то, как работает страница Настройки > Контакты > Сортировка.

Это показывает две строки. Один с Первым, последним, а другой с последним, первым. Когда пользователь нажимает на строку, он действует как радиокнопка, и в конце строки появляется отметка.

Я хотел бы попробовать реализовать эту функциональность, но я не уверен, с чего начать. Должен ли я делать это с помощью ViewCell или TextCell, и как у кого-нибудь есть идеи относительно того, как это реализовано?

.

Ответы

Ответ 1

EDIT 1: упрощенное свойство изменило логику в рендерере iOS; теперь нет ссылок или обработчиков для очистки.

В расширении до ответа @hankide:

Вы можете создать свойство bindable IsChecked при расширении TextCell или ViewCell и привязать к нему свое состояние виртуальной машины.

public class MyTextCell : TextCell
{
    public static readonly BindableProperty IsCheckedProperty =
        BindableProperty.Create(
            "IsChecked", typeof(bool), typeof(MyTextCell),
            defaultValue: false);

    public bool IsChecked
    {
        get { return (bool)GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }
}

Следующим шагом будет создание рендерера, который прослушивает это свойство и показывает контрольную отметку на уровне iOS.

[assembly: ExportRenderer(typeof(MyTextCell), typeof(SampleApp.iOS.MyTextCellRenderer))]
namespace SampleApp.iOS
{
    public class MyTextCellRenderer : TextCellRenderer
    {
        public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
        {
            var nativeCell = base.GetCell(item, reusableCell, tv);

            var formsCell = item as MyTextCell;
            SetCheckmark(nativeCell, formsCell);

            return nativeCell;
        }

        protected override void HandlePropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            base.HandlePropertyChanged(sender, args);

            System.Diagnostics.Debug.WriteLine($"HandlePropertyChanged {args.PropertyName}");
            if (args.PropertyName == MyTextCell.IsCheckedProperty.PropertyName)
            {
                var nativeCell = sender as CellTableViewCell;
                if (nativeCell?.Element is MyTextCell formsCell)
                    SetCheckmark(nativeCell, formsCell);
            }
        }

        void SetCheckmark(UITableViewCell nativeCell, MyTextCell formsCell)
        {
            if (formsCell.IsChecked)
                nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
            else
                nativeCell.Accessory = UITableViewCellAccessory.None;
        }
    }
}

Пример использования 1

И, например, использование образца:

<TableView Intent="Settings">
    <TableSection Title="Sort Order">
        <local:MyTextCell Text="First Last" IsChecked="false" />
        <local:MyTextCell Text="Last, First" IsChecked="true" />
    </TableSection>
</TableView>

Пример использования 2

Вы также можете прослушать событие Tapped, чтобы обеспечить, что свойство IsChecked работает как ожидалось.

Например, вы привязываете это свойство к ViewModel:

<TableView Intent="Settings">
    <TableSection Title="Sort Order">
        <local:MyTextCell Tapped="Handle_Tapped" Text="{Binding [0].Name}" IsChecked="{Binding [0].IsSelected}" />
        <local:MyTextCell Tapped="Handle_Tapped" Text="{Binding [1].Name}" IsChecked="{Binding [1].IsSelected}" />
    </TableSection>
</TableView>

и обработать событие нажатия:

public SettingViewModel[] Settings = new []{
    new SettingViewModel { Name = "First Last", IsSelected = false },
    new SettingViewModel { Name = "Last First", IsSelected = true },
};

void Handle_Tapped(object sender, System.EventArgs e)
{
    var cell = sender as TextCell;
    if (cell == null)
        return;

    var selected = cell.Text;
    foreach(var setting in Settings)
    {
        if (setting.Name == selected)
            setting.IsSelected = true;
        else
            setting.IsSelected = false;
    }
}

введите описание изображения здесь

Ответ 2

Страница настроек порядка сортировки реализована с использованием UIKit UITableView. В Xamarin.Forms вы можете использовать TableView, чтобы получить тот же результат.

Как вы быстро заметите, нет способа установить значок галочки с помощью Xamarin.Forms, поэтому вам, вероятно, понадобится создать пользовательскую ячейку, который имеет текст слева и изображение галочки справа.

Если вы действительно хотите сделать все по книге, вы, вероятно, должны создать собственный рендерер, который позволит вам установить Accessory свойство тока ViewCell. Однако это будет немного сложнее для такой небольшой функции.