代码之家  ›  专栏  ›  技术社区  ›  Apurva19

iOS上的ForceUpdateSize ListView问题

  •  9
  • Apurva19  · 技术社区  · 7 年前

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

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

    是否有替代解决方案来代替 强制更新大小 要在运行时动态扩展ListView行?

    2 回复  |  直到 7 年前
        1
  •  11
  •   Duke Y    6 年前

    在需要更改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。

        2
  •  0
  •   Ax1le    7 年前

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

    首先,定义一个bool列表,其项目等于要在源中显示的行。我第一次用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进行测试),如下所示:

    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事件。根据iExpanded中的项目设置大小值:

    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);