2013-11-04 166 views
0

有一點麻煩「reloadData」有一個UITableView工作。簡而言之;如果我將數據/行添加到表中,行將添加,但顯示爲現有行的重複項。如果我調試「DequeueReusableCell」它似乎只是返回一個隨機單元格。這是我的代碼。 (是的,它是C# - MonoTouch的,如果你知道在Objective-C的答案,只是張貼了,我很靈活)UITableView的reloadData複製細胞

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上看到的其他類似的問題,但沒有提供一個明確的答案......

回答

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; 
+0

我明顯誤解了DequeueReusableCell的工作方式。我在「更新」中做了一些額外的加載和計算,我希望這樣「緩存」,但顯然不會發生。所以基本上DequeueReusableCell的唯一用途就是確保內存中分配的單元總是有限的。 – reinder

+0

對。而不是在您滾動時配置和創建單元格,它只是緩存它們,所以您不必處理不斷創建它們的開銷。但是您回收的單元格可能會從其他行中獲取舊數據,因此您需要確保更新其內容。 – Jason

+0

好吧,這也解釋了「靜態」的標識,這點我也不明白:)學到了今天新。感謝堆 – reinder