• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

iOS : Expandable list view not drawing newly added control

[复制链接]
菜鸟教程小白 发表于 2022-12-12 14:59:49 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试使用带有 MvvmCross 的 Xamarin 在 iOS 中创建一个可扩展的 ListView 。

场景是我有一个 ListView ,当 ListView 中的一行被选中时,它会展开(动画)以显示一个 Collection View ,通过延迟加载加载。

这是我目前的代码:

适配器:

public class MercatoAnimatedExpandableTableSource : MvxTableViewSource
{
    private readonly string _key;
    private readonly List<object> items;
    private Dictionary<object, bool> expandableState = new Dictionary<object, bool>(); 

    public MercatoAnimatedExpandableTableSource(UITableView tableView, IEnumerable<object> items, UINib nib, string key)
        : base(tableView)
    {
        _key = key;
        this.items = items.ToList();
        this.items.ForEach(x => expandableState[x] = true);
        tableView.RegisterNibForCellReuse(nib, key);
    }

    protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
    {
        var cell = tableView.DequeueReusableCell(_key);

        cell.Frame = new RectangleF(cell.Frame.X, cell.Frame.Y, cell.Frame.Width, GetHeightForRow(tableView, indexPath));

        return cell;
    }

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        base.RowSelected(tableView, indexPath);

        var isExpanded = expandableState[items[indexPath.Row]];

        expandableState[items[indexPath.Row]] = !isExpanded;

        var row = this.GetCell(tableView, indexPath);

        (row as FamilysubgroupViewCell).ExpandCells();

        tableView.ReloadRows(new[] { indexPath }, UITableViewRowAnimation.Automatic); 
    }

    public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
    {
        var isExpanded = expandableState[items[indexPath.Row]];
        if (isExpanded)
        {
            return 25;
        }

        return 400;
    }

    protected override object GetItemAt(NSIndexPath indexPath)
    {
        return items[indexPath.Row];
    }
}

单元格:

    public FamilySubgroupViewCell (IntPtr handle) : base (handle)
    {
        this.DelayBind(() =>
        {
            this.FamilyCollectionViewContainer.BackgroundColor = UIColor.Blue;
            var bindingset = this.CreateBindingSet<FamilySubgroupViewCell, FamilySubTypeViewModel>();
            bindingset.Bind(this.FamilyGroupTitleLabel).To(x => x.FamilySubType.FamilySubGroupDescription);
            bindingset.Bind(this.FamilyGroupDescLabel).To(x => x.FamilySubType.FamilySubGroupDetail); 
            bindingset.Apply();
        });

    }

    public void ExpandCells(Action onUpdate)
    {
        var context = this.DataContext as FamilySubTypeViewModel;
        context.PopulateAndRun(() =>
        {
            Debug.WriteLine("opulating Models complete : now showing cells");
            var collection = new FamilySubGroupModelsCollection();
            collection.ViewModel = context;
            Debug.WriteLine("FamilySubGroupCell : Showing {0} Items", context.FamilyModels.Count);

            this.FamilyCollectionViewContainer.Add(collection.View);

            if (onUpdate != null) onUpdate();
        });
    }

问题

因此,当一个单元格被选中时,它会翻转 'isExpanded' 属性,赋予它一个新的高度 - 效果很好。然后向该单元格发送一条消息以“扩展”该单元格,然后加载一个新集合并将其添加到 View 中(通过 View 导出)。

但是,集合永远不会在 View 上重新呈现。它填充得很好,添加到 View 中,但它在新扩展的单元格上实际上是不可见的。如果我在 DelayBind() 方法中最初创建单元格时加载它(即 - 没有延迟加载),那么它可以正常工作。

尝试过重绘单元格之类的方法

this.Draw(this.Bounds);

将集合添加到 View 后,但无济于事。

我做错了什么?



Best Answer-推荐答案


感觉这段代码可能会混淆你的显示:

    var row = this.GetCell(tableView, indexPath);
    (row as FamilysubgroupViewCell).ExpandCells();
    tableView.ReloadRows(new[] { indexPath }, UITableViewRowAnimation.Automatic); 

这是做什么的:

  • 获取当前单元格并告诉它展开
  • 然后要求表格重新加载行(此时可能会使用不同的单元格实例)。

我也担心这行:

    var context = this.DataContext as FamilySubTypeViewModel;

会将您的单元格子显示链接到当前 View 模型 - 如果单元格被重复使用(给定新的 View 模型),这不会更新。

解决这两个问题的一种快速(而且只是稍微有点脏)的方法是将 GetOrCreateCellFor 的覆盖更改为:

protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
    var cell = tableView.DequeueReusableCell(_key);

    cell.Frame = new RectangleF(cell.Frame.X, cell.Frame.Y, cell.Frame.Width, GetHeightForRow(tableView, indexPath));

    ((MyCellType)cell).ShowExpandedState(expandableState[items[indexPath.Row]]);

    return cell;
}

ShowExpandedState(bool) 可以在重用后重置单元格的展开区域。


其他选项:

  • 除此之外,您可以简单地为展开行和非展开行返回不同的单元格类型?
  • 或者您可以将展开/未展开的信息放在 Cell 的 ViewModel 中,以便它可以数据绑定(bind)到该展开状态并更新它自己的布局? (不过,您仍然需要一些机制来告诉表格大小变化)

开启:

this.Draw(this.Bounds);

我并不感到惊讶这不起作用 - 通常你必须鼓励系统重绘 View - 使用诸如 SetNeedsDisplay 之类的东西(有时在子更改后 SetNeedsLayout 也是)

关于iOS : Expandable list view not drawing newly added control,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19091776/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap