"reloadData"가 UITableView와 함께 작동하는 데 약간의 문제가 있습니다. 간단히 말해서; 테이블에 데이터/행을 추가하면 행이 추가되지만 기존 행의 중복으로 표시됩니다. "DequeueReusableCell"디버깅하는 경우 그냥 임의의 셀을 반환하는 것. 여기 내 코드가있다.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
에서 일어나는 - (당신은 단지 그것을 게시, 목표 - C에서 답을 알고 있다면, monotouch 난 유연 해요 예는 C 번호입니다). 여기에 LoadingCell
(하단에로드 표시기가 있음)이 표시되는지 확인한 다음 이에 따라 추가 데이터를로드하고 내 IEnumerable에 추가합니다. 그런 다음 reloadData
을 호출 한 후 GetCell
으로 들어가고 DequeueReusableCell
은 "새"셀이라도 복제본을 반환합니다 ...
문제의 일부가 아니므로 모든 것을 제거했습니다. 내 getMyStuff
메서드에서 오류 처리, 어느 곳에서도 캐싱이없는 것처럼 보이지 않습니다. 그렇지 않으면 모범 사례에 대한 의견이 열려 있습니다.
나는 믿을 수 없을만큼 간단하다고 확신하지만, 나는 그저 머리를 감쌀 수 없다. StackOverflow에 다른 비슷한 질문을 본 적이 있지만 아무도 명확한 대답을 제공하지 않습니다 ...
분명히 DequeueReusableCell이 작동하는 방식에 대해 오해했습니다. 나는 "업데이트"에서 몇 가지 추가 로딩 및 계산을 수행하고 있는데, 나는이 방법으로 "캐시"하기를 원했지만 분명히 그렇게되지는 않습니다. 기본적으로 DequeueReusableCell을 사용하는 유일한 방법은 메모리에 할당 된 셀의 수가 제한되어 있는지 확인하는 것입니다. – reinder
오른쪽. 스크롤 할 때 셀을 폐기하고 생성하는 대신 셀을 캐시하기 만하면 끊임없이 오버 헤드를 생성 할 필요가 없습니다. 하지만 가져온 셀에는 다른 행의 오래된 데이터가있을 수 있으므로 내용을 업데이트해야합니다. – Jason
그래, 나도 이해하지 못하는 "정적"식별자를 설명한다. 오늘 새로운 것을 배웠다. 고마워. – reinder