[TIMOB-18680] iOS - Incorrect Caching of ListItems containing Textfields
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2015-03-17T21:21:11.000+0000 |
Affected Version/s | Release 3.5.1 |
Fix Version/s | Release 4.1.0 |
Components | iOS |
Labels | ListItem, ListView, index |
Reporter | Justin Toth |
Assignee | Vishal Duggal |
Created | 2015-03-04T23:10:06.000+0000 |
Updated | 2015-06-15T08:31:41.000+0000 |
Description
One of our Titanium apps uses ListViews extensively, including for building forms, where each ListItem contains a form control (TextField, Picker, etc...) If the form has more ListItems than the size of the screen, as you scroll down it causes issues where the values from certain TextFields are copied into other ListItems' TextFields.
This is clearly connected to the ListView's row caching, it's expected that it would cache the list rows so that you only have as many as are on the screen in memory, however it's clearly not setting the values correctly for each row as scrolling occurs.
I've boiled it down to a simple reproduction case below, simply input values into the first few rows (e.g. "test 1", "test 2", "test 3") then scroll down and you'll see those 3 values populated into other rows.
var win = Ti.UI.createWindow({ backgroundColor: 'white' });
var defaultTemplate = {
childTemplates: [
{
type: 'Ti.UI.Label',
bindId: 'label',
properties: {
top: '5dp', left: '5dp'
}
},
{
type: 'Ti.UI.TextField',
bindId: 'value',
properties: {
top: '30dp', left: '5dp', right: '5dp', bottom: '5dp',
backgroundColor: 'gray', color: 'black', height: '40dp'
}
}
]
};
var listView = Ti.UI.createListView({
top: '20dp',
templates: { 'default': defaultTemplate },
defaultItemTemplate: 'default',
rowHeight: '70dp',
backgroundColor: '#eff3fa',
showVerticalScrollIndicator: true,
separatorColor: '#e3ece7', separatorInsets: { left: 0, right: 0 }
});
var items = [];
for (var k=0;k<40;k++) {
var label = 'Item ' + (k + 1);
items.push({
label: { text: label },
value: { text: '' }
});
}
var sections = [
Ti.UI.createListSection({
headerTitle: 'Only Section',
items: items
})
];
listView.setSections(sections);
win.add(listView);
win.open();
Hi Justin, What you are seeing is the default behavior. To update the content of the textfield, you need to update the data. There's documentation here: http://docs.appcelerator.com/titanium/latest/#!/guide/ListViews For example, I changed the template to make it more readable, value is now called textField. I also added an event to the textfield.
Then declare the event function to be called, and there update the listview data:
Resolving, this is not a bug
It seems like you didn't test your code, as it still has the same issue as in my original sample... The issue is that rows are cached and reused, simply updating the textfield's value manually on blur does nothing to address that issue. It also leaves a nasty side effect where if you click from one textfield to another, the second one won't gain focus, as the section.updateItemAt will recreate the section and focus is lost. Please reopen the ticket.
A couple of issues with the sample code. One the property to be used with the
textField
bindId isvalue
nottext
. Second the reason the keyboard disappears on selecting a second text field is because the updateItemAt does not specify an animated parameter which implicitly sets animated to false. In this scenario we have to reload the whole table. Either ways there is an issue with ListView's reuse of Proxies and underlying views. Will setup a PR to fix this. Test casePull pending master - https://github.com/appcelerator/titanium_mobile/pull/6718
I've tested and confirmed that the row caching issue is resolved when using master and the two changes that Vishal suggested (value instead of text and animated: true). Thanks Pedro and Vishal for looking into the issue!
The issue is fixed. No caching of list items. Verified using the code mentioned by Vishal. Verified on: Mac OS 10.10.1 Ti SDK: 4.1.0.v20150614181235 Appc Studio: 4.1.0.201506120823 Appc CLI Registry: 4.0.2 Appc CLI NPM: 4.0.1 Device: iPhone 6plus (v8.3), iPhone 5S simulator (v7.1)