UITableView reloadData重复单元格

时间:2013-11-04 20:02:06

标签: c# ios objective-c uitableview xamarin.ios

让“reloadData”与UITableView一起工作时遇到一些麻烦。简而言之;如果我向表中添加数据/行,则行将添加,但显示为现有行的副本。如果我调试“DequeueReusableCell”,它似乎只返回一个随机单元格。这是我的代码。 (是的,它是C# - monotouch,如果你知道Objective-C中的答案,只需发布​​它,我很灵活)

public partial class MyViewController : UITableViewController
{
    AppDelegate AppDelegate;
    MyStuff sendToDetail;
    MyRestClient client;

    public MyViewController (IntPtr handle) : base (handle)
    {
        AppDelegate = (AppDelegate)UIApplication.SharedApplication.Delegate;
        client = new MyRestClient();
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        this.TableView.Source = new TableSource(getMyStuff (), this);
    }

    public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
    {
        base.PrepareForSegue (segue, sender);

        if (segue.Identifier == "DetailSegue") {
            DetailController controller = segue.DestinationViewController as DetailController;
            controller.MyStuffItem = sendToDetail;
        }
    }

    private IEnumerable<MyStuff> getMyStuff(int skip = 0, int count = 10)
    {
        var request = new RestRequest("MyStuff");
        request.AddParameter("id", AppDelegate.ActiveUser.Id);
        request.AddParameter("$top", count);
        request.AddParameter("$skip", skip);
        var response = client.Execute(request);

        var source = (IEnumerable<MyStuff>)JsonConvert.DeserializeObject(response.Content, typeof(IEnumerable<MyStuff>));

        return source;
    }

    public class TableSource : UITableViewSource {
        IEnumerable<MyStuff> tableItems;
        MyViewController Controller;

        public TableSource (IEnumerable<MyStuff> items, MyViewController controller)
        {
            tableItems = items;
            Controller = controller;
        }

        public override int NumberOfSections (UITableView tableView)
        {
            return 1;
        }

        public override int RowsInSection (UITableView tableview, int section)
        {
            return tableItems.Count() + 1;
        }

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

            if (indexPath.Row == tableItems.Count()) {
                //bottom load more cell

                LoadingCell loadMore = tableView.DequeueReusableCell ("LoadingCell") as LoadingCell;
                if (loadMore == null)
                    loadMore = LoadingCell.Create ();

                return loadMore;
            }

            MyStuffCell cell = tableView.DequeueReusableCell ("MyStuffCell") as MyStuffCell;
            // if there are no cells to reuse, create a new one
            if (cell == null) {
                cell = MyStuffCell.Create ();

                MyStuff current = tableItems.ElementAt (indexPath.Row);

                cell.Update (current);
            }

            return cell;
        }

        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            if (indexPath.Row != tableItems.Count()) {
                Controller.sendToDetail = tableItems.ElementAt (indexPath.Row);
                Controller.PerformSegue ("DetailSegue", this);
            }
        }

        public override void WillDisplay (UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
        {
            if (cell is LoadingCell) {
                var count = tableItems.Count ();
                var second = Controller.getMyStuff (count);
                tableItems = tableItems.Concat (second);
                tableView.ReloadData ();
            }
        }
    }
}

神奇发生在WillDisplay。在这里,我检查它是否会显示LoadingCell(底部带有加载指示符)并将相应地加载额外数据并将其添加到我的IEnumerable中。然后在调用reloadData后,它将进入GetCell并且DequeueReusableCell会返回重复的内容......即使对于“新”单元格...

我删除了不属于问题的所有内容,这是真的:我的getMyStuff方法中没有错误处理,似乎我没有任何缓存......否则我'开放最佳实践评论。

我确信它简直令人难以置信,但我无法绕过它。我在StackOverflow上看过其他类似的问题,但没有一个提供明确的答案......

1 个答案:

答案 0 :(得分:2)

DequeueReusableCell只从它的内部缓存中返回一个已分配的Cell对象。您仍然需要更新单元格的内容以反映适合该部分/行的任何内容。

        MyStuffCell cell = tableView.DequeueReusableCell ("MyStuffCell") as MyStuffCell;
        // if there are no cells to reuse, create a new one
        if (cell == null) {
            cell = MyStuffCell.Create ();
        }

        MyStuff current = tableItems.ElementAt (indexPath.Row);
        cell.Update (current);

        return cell;