iOS

时间:2018-01-10 08:52:45

标签: ios listview xamarin xamarin.forms custom-renderer

我有一个自定义ListView使用带有单选按钮的自定义ViewCells。单击每个单选按钮时,ListView会动态调整其高度以隐藏/显示注释框。

在iOS平台上使用ForceUpdateSize时,单击单选按钮时ListView性能会迅速降低。该应用程序最终会挂起并停止响应。

是否有替代ForceUpdateSize的替代解决方案在运行时动态扩展ListView行?

2 个答案:

答案 0 :(得分:8)

定义ViewCell尺寸更改事件,无论您需要更改ViewCell尺寸

public static event Action ViewCellSizeChangedEvent; 

在您的情况下,它应该由您的单选按钮触发。这样称呼:

ViewCellSizeChangedEvent?.Invoke();

然后,它将使用ListView渲染器更新iOS TableView。

public class CustomListViewRenderer : ListViewRenderer
{
    public CustomListViewRenderer()
    {
        WhatEverContentView.ViewCellSizeChangedEvent += UpdateTableView;
    }

    private void UpdateTableView()
    {
        var tv = Control as UITableView;
        if (tv == null) return;
        tv.BeginUpdates();
        tv.EndUpdates();
    }
}

它应该在继续使用Xaml的同时解决您的性能问题,而不是创建不需要的自定义ViewCell。

答案 1 :(得分:0)

我的解决方案是:尝试使用自定义渲染器。单击该按钮时,我使用tableView.ReloadRows()动态更改单元格的大小。

首先,定义一个bool列表,其项目等于要在Source中显示的行数。我第一次用false初始化它的项目。

List<bool> isExpanded = new List<bool>();

public MyListViewSource(MyListView view)
{
    //It depends on how many rows you want to show.
    for (int i=0; i<10; i++) 
    {
        isExpanded.Add(false);
    }
}

其次,构建GetCell事件(我只是将UISwitch放在我的Cell中进行测试),如:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{

    MyListViewCell cell = tableView.DequeueReusableCell("Cell") as MyListViewCell;

    if (cell == null)
    {
        cell = new MyListViewCell(new NSString("Cell"));

        //This event is constructed in my Cell, when the switch's value changed it will be fired.
        cell.RefreshEvent += (refreshCell, isOn) =>
        {
            NSIndexPath index = tableView.IndexPathForCell(refreshCell);
            isExpanded[index.Row] = isOn;
            tableView.ReloadRows(new NSIndexPath[] { index }, UITableViewRowAnimation.Automatic);
        };
    }

    cell.switchBtn.On = isExpanded[indexPath.Row];

    return cell;
}

最后,我们可以覆盖GetHeightForRow事件。根据isExpanded:

中的项目设置大值或小值
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
    if (isExpanded[indexPath.Row])
    {
        return 80;
    }
    return 40;
}

以下是我的单元格的一部分:

//When switch's value changed, this event will be called
public delegate void RefreshHanle(MyListViewCell cell, bool isOn);
public event RefreshHanle RefreshEvent;
switchBtn.AddTarget((sender, args) =>
{
    UISwitch mySwitch = sender as UISwitch;
    RefreshEvent(this, mySwitch.On);
}, UIControlEvent.ValueChanged);