Hi.
By now I’ve read a bunch about this issue.
I have a foreach iterating over a dictionary, instantiating objects with a Toggle component and I’m adding an event handler for the ValueChanged event in it, passing the dictionary key as a parameter.
Of course, the loop Pair<int,string> is captured. I read about that. The callback always gets the last key, because we’ve been changing the same variable that it has.
So I did what everybody said: take a local copy inside of the loop.
It doesn’t work. I get the same result as when using the pair.Key directly.
Edit: I thought even’t wasn’t firing and it was (since log had the same number, it was grouped!), so I’ve removed all references to that issue. Lambda issue is still there though.
Summary:
-Local copy to break out of the lambda closure is not working. Why? How should it be done?
Here’s the code:
Transform newToggleTransform;
RectTransform newToggleRect;
Toggle newToggle;
Text newToggleText;
ToggleId newToggleId;
float xPos = 0;
foreach (KeyValuePair<int,string> pair in retails) {
newToggleTransform = Instantiate(retailTogglePrefab, new Vector3(xPos, 0, 0), Quaternion.identity) as Transform;
newToggleTransform.SetParent(retailGroupPanel,false);
newToggle = newToggleTransform.GetComponent<Toggle> ();
newToggle.isOn = false;
if (xPos == 0) {
newToggle.isOn = true; // doesn't fire, as expected
activateRetail(true,pair.Key); // so we call the callback manually. This works :)
Debug.Log ("toggled because xPos == 0");
}
newToggle.group = retailGroupPanel.GetComponent<ToggleGroup> ();
newToggleText = newToggleTransform.GetComponent<Text> ();
newToggleText.text = pair.Value; // retailName
newToggleId = newToggleTransform.GetComponent<ToggleId> ();
newToggleId.toggleId = pair.Key; // retailId <-- do we even need this?
newToggleRect = newToggleTransform.GetComponent<RectTransform> ();
int temp = pair.Key;
newToggle.onValueChanged.AddListener((value) => {
Debug.Log ("listener fired, calling with "+temp.ToString()); // called only once, with the last key :(
activateRetail(value,temp);
});
xPos += newToggleRect.rect.width;
}