使用For-Each循环创建TableView

时间:2016-12-20 06:42:21

标签: c# android ios unity3d tableview

我正在使用Unity3D资产为我的应用程序创建一个TableView。但是当我尝试在for-each循环中从一个对象移动到另一个对象时,它只显示响应中的最后一个对象。这就是我的意思:

enter image description here

以下是我尝试创建单元格的代码(仅供参考我使用GameSparks作为后端服务):

//Will be called by the TableView to know how many rows are in this table
public int GetNumberOfRowsForTableView (TableView tableView)
{
    return 10;
}

//Will be called by the TableView to know what is the height of each row
public float GetHeightForRowInTableView (TableView tableView, int row)
{
    return (m_cellPrefab.transform as RectTransform).rect.height;
}

//Will be called by the TableView when a cell needs to be created for display
public TableViewCell GetCellForRowInTableView (TableView tableView, int row)
{
    LeaderboardCell cell = tableView.GetReusableCell (m_cellPrefab.reuseIdentifier) as LeaderboardCell;

    if (cell == null) {
        cell = (LeaderboardCell)GameObject.Instantiate (m_cellPrefab);
        new GameSparks.Api.Requests.LeaderboardDataRequest ().SetLeaderboardShortCode ("High_Score_Leaderboard").SetEntryCount (100).Send ((response) => {
            if (!response.HasErrors) {
                resp = response;
                Debug.Log ("Found Leaderboard Data...");

            } else {
                Debug.Log ("Error Retrieving Leaderboard Data...");
            }
        });
    }

    foreach (GameSparks.Api.Responses.LeaderboardDataResponse._LeaderboardData entry in resp.Data) {
        int rank = (int)entry.Rank;
        //model.Rank =rank;
        string playerName = entry.UserName;
        cell.name = playerName;
        string score = entry.JSONData ["SCORE"].ToString ();
        cell.SetScore(score);
        //string fbid = entry.ExternalIds.GetString("FB").ToString();
        //model.facebookId = fbid;
        Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
    }
    return cell;
}

2 个答案:

答案 0 :(得分:1)

首先实例化单元格变量,然后对resp.Data执行for循环。问题是,您只需浏览所有数据,并在每次迭代时设置名称并设置分数。每次迭代都会覆盖这些值,然后在循环结束时返回最后一个版本的单元格。 根据你在GetCellForRowInTableView方法之上的注释,你不应该真正在那里循环,因为这个方法应该为每个项目调用一次。因此,您想要做的而不是循环是这样的:

public TableViewCell GetCellForRowInTableView (TableView tableView, int row)
{
    LeaderboardCell cell = tableView.GetReusableCell (m_cellPrefab.reuseIdentifier) as LeaderboardCell;

    if (cell == null) {
        cell = (LeaderboardCell)GameObject.Instantiate (m_cellPrefab);
        new GameSparks.Api.Requests.LeaderboardDataRequest ().SetLeaderboardShortCode ("High_Score_Leaderboard").SetEntryCount (100).Send ((response) => {
            if (!response.HasErrors) {
                resp = response;
                Debug.Log ("Found Leaderboard Data...");

            } else {
                Debug.Log ("Error Retrieving Leaderboard Data...");
            }
        });
    }

    var entry = resp.Data[row];
        int rank = (int)entry.Rank;
        //model.Rank =rank;
        string playerName = entry.UserName;
        cell.name = playerName;
        string score = entry.JSONData ["SCORE"].ToString ();
        cell.SetScore(score);
        //string fbid = entry.ExternalIds.GetString("FB").ToString();
        //model.facebookId = fbid;
        Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);

    return cell;
}

答案 1 :(得分:1)

你的问题是foreach循环的一个经典问题。基本上,系统使用集合中的新索引项覆盖当前引用。因此,尽管您将值存储在局部变量中,但您的条目引用会被覆盖,然后所有值都指向最后的相同条目对象。

解决方案是创建本地条目参考:

   foreach (GameSparks.Api.Responses.LeaderboardDataResponse._LeaderboardData entry in resp.Data) {
        var localEntry = entry; // New line
        int rank = (int)localEntry.Rank; // entry is replaced with local
        string playerName = localEntry.UserName; 
        cell.name = playerName;
        string score = localEntry.JSONData ["SCORE"].ToString (); line 
        cell.SetScore(score);
        Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
    }

编辑:我看到你在循环外返回单元格,所以即使循环修复了一个问题,你还有另一个问题。

在每个循环中查看,您正在填充单元格数据。但是在每个循环中,您都要覆盖单元格数据。最后,您返回最后一个值。 您可以返回一个单元格数组,然后使用数组创建项目,或者将项目数组传递给方法,这样对于循环的每次迭代,您还可以设置匹配项目的值(使用索引)。 / p>