{ "id": "104923", "key": "TIMOB-11760", "fields": { "issuetype": { "id": "5", "description": "The sub-task of the issue", "name": "Sub-task", "subtask": true }, "parent": { "id": "98489", "key": "TIMOB-11510", "fields": { "summary": "iOS: TableView very slow", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "13505", "description": "Release 3.0.0", "name": "Release 3.0.0", "archived": true, "released": true, "releaseDate": "2012-12-14" }, { "id": "14162", "description": "Release 3.1.0", "name": "Release 3.1.0", "archived": true, "released": true, "releaseDate": "2013-04-16" }, { "id": "14624", "description": "2012 Sprint 24 JS", "name": "2012 Sprint 24", "archived": true, "released": true, "releaseDate": "2012-12-03" }, { "id": "14626", "description": "2012 Sprint 24 Core", "name": "2012 Sprint 24 Core", "archived": true, "released": true, "releaseDate": "2012-12-03" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2012-11-20T23:08:06.000+0000", "created": "2012-11-14T00:52:44.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "core", "tableview" ], "versions": [], "issuelinks": [ { "id": "22943", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "104752", "key": "TIMOB-11715", "fields": { "summary": "iOS: Animation - Animations are missing while adding and removing view.", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "22958", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "104854", "key": "TIMOB-11745", "fields": { "summary": "iOS TableViewRow structures for className meh does not match", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-16T21:03:00.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "Test case\r\n{code}\r\nvar REUSABLE = true;\r\nvar win = Ti.UI.createWindow();\r\nvar tableView = Ti.UI.createTableView();\r\nvar toolbar = createToolbar();\r\nvar data = [];\r\nvar selectedRows = {};\r\nvar nbSelected = 0;\r\n \r\nfunction createRow(c) {\r\n var row = Ti.UI.createTableViewRow({\r\n selectionStyle:'none',\r\n\t\treusable: REUSABLE\r\n });\r\n row.selected = false;\r\n row.unread = !! Math.round(Math.random() * 1);\r\n row.starred = !! Math.round(Math.random() * 1);\r\n row.attachment = !! Math.round(Math.random() * 1);\r\n var important=Math.floor(Math.random()*5);\r\n var label=Math.floor(Math.random()*3);\r\n row.selectedBackgroundColor = '';\r\n row.height = 80;\r\n row.className = 'datarow';\r\n row.clickName = 'row';\r\n \r\n \r\n var selectButton = Ti.UI.createView({\r\n backgroundImage:'images/select_off.png',\r\n left:10,\r\n width:20,\r\n height:20,\r\n clickName:'select'\r\n });\r\n \r\n var viewCenter = Ti.UI.createView({\r\n layout:'vertical', \r\n left:40, \r\n right:40\r\n });\r\n \r\n var viewSenderDate = Ti.UI.createView({\r\n height:30,\r\n bottom:5\r\n });\r\n \r\n var senderView = Ti.UI.createLabel({\r\n color:'black',\r\n font:{fontSize:16,fontWeight:(row.unread?'bold':'normal')},\r\n left:0,\r\n top:0,\r\n height:Ti.UI.FILL,\r\n right:50,\r\n clickName:'user',\r\n text:'Fred Smith '\r\n });\r\n \r\n var attachmentView = Ti.UI.createView({\r\n backgroundImage:'images/button_attach.png',\r\n right:38,\r\n top:5,\r\n width:24,\r\n height:16,\r\n clickName:'attachment'\r\n });\r\n attachmentView.visible = row.attachment;\r\n \r\n var dateView = Ti.UI.createLabel({\r\n color:'#444',\r\n font:{fontSize:14,fontWeight:'normal'},\r\n width:35,\r\n top:0,\r\n right:0,\r\n height:20,\r\n clickName:'date',\r\n text:'7/31'\r\n });\r\n \r\n var viewimportanceSubject = Ti.UI.createView({\r\n height:20\r\n });\r\n \r\n var importanceView = Ti.UI.createView({\r\n left:0,\r\n width:16,\r\n height:10,\r\n clickName:'importance'\r\n });\r\n \r\n \r\n var subjectView = Ti.UI.createLabel({\r\n color:(row.unread?'black':'#444'),\r\n font:{fontSize:14,fontWeight:(row.unread?'bold':'normal')},\r\n left:20,\r\n top:0,\r\n height:Ti.UI.FILL,\r\n right:0,\r\n wordWrap:false,\r\n clickName:'subject',\r\n text:'This is a sample subject'\r\n });\r\n \r\n if (important === 0)\r\n {\r\n subjectView.left = 0;\r\n importanceView.visible = false;\r\n }\r\n else\r\n importanceView.backgroundImage = '/images/importance' + important + '.png';\r\n \r\n var viewmessageLabels = Ti.UI.createView({\r\n height:20\r\n });\r\n \r\n var messageView = Ti.UI.createLabel({\r\n color:'#444',\r\n font:{fontSize:14,fontWeight:'bold'},\r\n left:0,\r\n top:0,\r\n height:Ti.UI.FILL,\r\n wordWrap:false,\r\n clickName:'message',\r\n text:'This is a sample core message text which actually needs to be pretty long so that we see what we want to see'\r\n });\r\n \r\n // var labelsView = Ti.UI.createWebView({\r\n // color:'#444',\r\n // top:0,\r\n // height:24,\r\n // right:0,\r\n // wordWrap:false,\r\n // clickName:'labels'\r\n // });\r\n // labelsView.html = '
Label
';\r\n // labelsView.width = label*25;\r\n // messageView.right = labelsView.width;\r\n \r\n var starButton = Ti.UI.createView({\r\n right:10,\r\n width:20,\r\n height:20,\r\n clickName:'star'\r\n });\r\n starButton.backgroundImage = 'images/star_' + (row.starred?'on':'off') + '.png';\r\n \r\n viewSenderDate.add(senderView);\r\n viewSenderDate.add(attachmentView);\r\n viewSenderDate.add(dateView);\r\n \r\n viewimportanceSubject.add(importanceView);\r\n viewimportanceSubject.add(subjectView);\r\n \r\n viewmessageLabels.add(messageView);\r\n // viewmessageLabels.add(labelsView);\r\n \r\n viewCenter.add(viewSenderDate);\r\n viewCenter.add(viewimportanceSubject);\r\n viewCenter.add(viewmessageLabels);\r\n \r\n row.add(selectButton);\r\n row.add(viewCenter);\r\n row.add(starButton);\r\n \r\n row.select = function()\r\n {\r\n this.backgroundColor = '#D9E7FD';\r\n this.separatorColor = '#B9CFF5';\r\n this.selected = true;\r\n selectButton.backgroundImage = 'images/select_on.png';\r\n }\r\n \r\n row.unselect = function()\r\n {\r\n this.backgroundColor = this.unread?'white':'#efefef';\r\n this.separatorColor = '#777';\r\n this.selected = false;\r\n selectButton.backgroundImage = 'images/select_off.png';\r\n }\r\n \r\n row.star = function()\r\n {\r\n this.starred = true;\r\n starButton.backgroundImage = 'images/star_' + (this.starred?'on':'off') + '.png';\r\n }\r\n \r\n row.unstar = function()\r\n {\r\n this.starred = false;\r\n starButton.backgroundImage = 'images/star_' + (this.starred?'on':'off') + '.png';\r\n }\r\n \r\n row.unselect();\r\n return row;\r\n}\r\n \r\nvar updating = false;\r\nvar loadingRow = Ti.UI.createTableViewRow({\r\n height:80,\r\n title:\"Show more messages...\",\r\n clickName: 'loadingRow',\r\n color:'blue'\r\n});\r\n \r\nfunction addRows()\r\n{\r\n updating = true;\r\n tableView.deleteRow(loadingRow);\r\n var lastCurrentRow = data.length -1;\r\n var lastRow = 50;\r\n for (var c=0;c 0)\r\n// tableView.scrollToIndex(lastCurrentRow,{animated:false,position:Ti.UI.iPhone.TableViewScrollPosition.BOTTOM}); \r\n tableView.appendRow(loadingRow);\r\n updating = false;\r\n}\r\n \r\ntableView.addEventListener('click', function(e){\r\n if (e.source.clickName === 'loadingRow')\r\n addRows();\r\n else if (e.source.clickName === 'select')\r\n {\r\n if (e.row.selected)\r\n {\r\n delete selectedRows[e.index];\r\n e.row.unselect();\r\n nbSelected -= 1;\r\n toolbar.setNbSelected(nbSelected);\r\n if (nbSelected === 0)\r\n toolbar.hideMe();\r\n }\r\n else\r\n {\r\n selectedRows[e.index] = e.row;\r\n e.row.select();\r\n nbSelected += 1;\r\n toolbar.setNbSelected(nbSelected);\r\n if (nbSelected === 1) //first selected\r\n toolbar.showMe();\r\n }\r\n }\r\n else if (e.source.clickName === 'star')\r\n {\r\n if (e.row.starred)\r\n e.row.unstar();\r\n else\r\n e.row.star();\r\n }\r\n \r\n})\r\n \r\naddRows();\r\nwin.add(tableView);\r\nwin.add(toolbar);\r\n \r\nfunction createToolbar()\r\n{\r\n var toolbar = Ti.UI.createView({\r\n left:-1,\r\n right:-1,\r\n height:38,\r\n bottom:-1,\r\n borderColor:'#6E6E6F',\r\n borderWidth:1,\r\n backgroundGradient: {\r\n type: 'linear',\r\n startPoint: { x: '50%', y: 0 },\r\n endPoint: { x: '50%', y:'100%' },\r\n colors: [ { color: '#424245', offset: 0.0}, { color: '#181819', offset: 1.0 } ],\r\n backfillStart:true\r\n }\r\n });\r\n toolbar.transform = Ti.UI.create2DMatrix().translate(0,toolbar.height);\r\n \r\n \r\n var labelNbSelected = Ti.UI.createLabel({\r\n color:'white',\r\n textAlign:'center',\r\n font:{fontSize:14,fontWeight:'normal'},\r\n left:10,\r\n width:25,\r\n height:25,\r\n wordWrap:false,\r\n backgroundColor:'#48484A',\r\n borderRadius:2\r\n });\r\n \r\n toolbar.setNbSelected = function(_nb)\r\n {\r\n labelNbSelected.text = _nb;\r\n }\r\n \r\n var buttonUnselect = Ti.UI.createButton({\r\n image:'images/button_close.png',\r\n style:'plain',\r\n font:{fontSize:15,fontWeight:'normal'},\r\n right:5,\r\n width:30,\r\n height:30\r\n });\r\n \r\n buttonUnselect.addEventListener('click', function(_event)\r\n {\r\n if (nbSelected === 0) return;\r\n for (var index in selectedRows)\r\n {\r\n selectedRows[index].unselect();\r\n }\r\n selectedRows = {};\r\n nbSelected = 0;\r\n toolbar.setNbSelected(0);\r\n toolbar.hideMe();\r\n });\r\n \r\n \r\n toolbar.showMe = function()\r\n {\r\n var animation = Ti.UI.createAnimation();\r\n animation.transform = Ti.UI.create2DMatrix();\r\n toolbar.animate(animation);\r\n }\r\n \r\n toolbar.hideMe = function()\r\n {\r\n var animation = Ti.UI.createAnimation();\r\n animation.transform = Ti.UI.create2DMatrix().translate(0,toolbar.height);\r\n toolbar.animate(animation);\r\n }\r\n \r\n toolbar.add(labelNbSelected);\r\n toolbar.add(buttonUnselect);\r\n return toolbar;\r\n}\r\nwin.add(toolbar);\r\n \r\nwin.open();\r\n{code}\r\n\r\nRun the example above in Instruments with REUSABLE both true and false.\r\nIn case REUSABLE=true, number of TiUITableViewRowContainer instances should match number of UITableViewCell.\r\nIn case REUSABLE=false (default), number of TiUITableViewRowContainer instances should grow as scrolled down, but not up. On simulate memory warning it should drop to number of visible UITableViewCells.\r\n", "attachment": [], "flagged": false, "summary": "Make TableViewRow reuse conditional", "creator": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "227247", "author": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR https://github.com/appcelerator/titanium_mobile/pull/3424", "updateAuthor": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-11-14T01:01:01.000+0000", "updated": "2012-11-14T01:01:01.000+0000" }, { "id": "228308", "author": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "body": "3_0_X PR https://github.com/appcelerator/titanium_mobile/pull/3464", "updateAuthor": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-11-21T22:33:00.000+0000", "updated": "2012-11-21T22:33:00.000+0000" }, { "id": "232501", "author": { "name": "crossbits", "key": "crossbits", "displayName": "Danny Pham", "active": true, "timeZone": "Europe/Berlin" }, "body": "Is this feature already available in latest release SDK 3.0.0 GA?\r\n\r\nBecause it didn't find anything about it in the official docs and with Instruments I see no differences using reusable=true or reusable=false.", "updateAuthor": { "name": "crossbits", "key": "crossbits", "displayName": "Danny Pham", "active": true, "timeZone": "Europe/Berlin" }, "created": "2012-12-24T08:47:24.000+0000", "updated": "2012-12-24T08:47:24.000+0000" }, { "id": "413031", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-16T21:03:00.000+0000", "updated": "2017-03-16T21:03:00.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }