有一點麻煩「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
後,將進入GetCell
和DequeueReusableCell
回報重複的......即使是一個「新」電池...
我刪除一切不是問題的一部分,所以真的不夠:沒有錯誤在我getMyStuff
方法處理,它也不會看起來像我在任何地方緩存...否則我打開最佳實踐意見。
我敢肯定,這是令人難以置信的東西簡單,但我不能換我的頭周圍。我在這裏StackOverflow上看到的其他類似的問題,但沒有提供一個明確的答案......
我明顯誤解了DequeueReusableCell的工作方式。我在「更新」中做了一些額外的加載和計算,我希望這樣「緩存」,但顯然不會發生。所以基本上DequeueReusableCell的唯一用途就是確保內存中分配的單元總是有限的。 – reinder
對。而不是在您滾動時配置和創建單元格,它只是緩存它們,所以您不必處理不斷創建它們的開銷。但是您回收的單元格可能會從其他行中獲取舊數據,因此您需要確保更新其內容。 – Jason
好吧,這也解釋了「靜態」的標識,這點我也不明白:)學到了今天新。感謝堆 – reinder