0

让“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它会进入GetCellDequeueReusableCell返回一个副本......即使是“新”单元格......

我删除了不属于问题的所有内容,非常真实:我的getMyStuff方法中没有错误处理,看起来我也没有任何缓存......否则我愿意接受最佳实践评论。

我敢肯定这是非常简单的事情,但我就是无法理解它。我在 StackOverflow 上看到了其他类似的问题,但没有一个提供明确的答案......

4

1 回答 1

3

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;
于 2013-11-04T20:12:17.857 回答