{ "id": "136219", "key": "AC-1306", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "12217", "key": "AC", "name": "Appcelerator - INBOX", "projectCategory": { "id": "10000", "description": "", "name": "Customer Service" } }, "resolution": { "id": "5", "description": "All attempts at reproducing this issue failed, or not enough information was available to reproduce the issue. Reading the code produces no clues as to why this behavior would occur. If more information appears later, please reopen the issue.", "name": "Cannot Reproduce" }, "resolutiondate": "2015-09-02T05:52:24.000+0000", "created": "2014-09-08T16:24:48.000+0000", "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "shossain", "key": "shossain", "displayName": "Shak Hossain", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2016-03-08T07:37:42.000+0000", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "14548", "name": "Titanium SDK & CLI", "description": "Please enter tickets related to the MobileSDK here." } ], "description": "Hello.\r\n\r\n\r\nTo see this issue, run this code:\r\n\r\n{code}\r\nvar win = Ti.UI.createWindow({backgroundColor: 'white', top: 20});\r\nvar listView = Ti.UI.createListView({height:'90%', top:0});\r\nvar sections = [];\r\n\r\nvar fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'});\r\nvar fruitDataSet = [\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Banana'}},\r\n];\r\nfruitSection.setItems(fruitDataSet);\r\nsections.push(fruitSection);\r\n\r\nvar vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'});\r\nvar vegDataSet = [\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Potatoes'}},\r\n];\r\nvegSection.setItems(vegDataSet);\r\n\r\nvar fishSection = Ti.UI.createListSection({ headerTitle: 'Fish'});\r\nvar fishDataSet = [\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Haddock'}},\r\n];\r\nfishSection.setItems(fishDataSet);\r\nlistView.sections = sections;\r\nvar refreshCount = 0;\r\n\r\nfunction getFormattedDate(){\r\n var date = new Date();\r\n return date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes();\r\n}\r\n\r\nfunction resetPullHeader(){\r\n actInd.hide();\r\n imageArrow.transform=Ti.UI.create2DMatrix();\r\n if (refreshCount < 2) {\r\n imageArrow.show();\r\n labelStatus.text = 'Pull down to refresh...';\r\n labelLastUpdated.text = 'Last Updated: ' + getFormattedDate();\r\n } else {\r\n labelStatus.text = 'Nothing To Refresh';\r\n labelLastUpdated.text = 'Last Updated: ' + getFormattedDate();\r\n listView.removeEventListener('pull', pullListener);\r\n listView.removeEventListener('pullend', pullendListener);\r\n eventStatus.text = 'Removed event listeners.';\r\n }\r\n listView.setContentInsets({top:0}, {animated:true});\r\n}\r\n\r\nfunction loadTableData()\r\n{\r\n if (refreshCount == 0) {\r\n listView.appendSection(vegSection);\r\n } else if (refreshCount == 1) {\r\n listView.appendSection(fishSection);\r\n } \r\n refreshCount ++;\r\n resetPullHeader();\r\n}\r\n\r\nfunction pullListener(e){\r\n eventStatus.text = 'EVENT pull FIRED. e.active = '+e.active;\r\n if (e.active == false) {\r\n var unrotate = Ti.UI.create2DMatrix();\r\n imageArrow.animate({transform:unrotate, duration:180});\r\n labelStatus.text = 'Pull down to refresh...';\r\n } else {\r\n var rotate = Ti.UI.create2DMatrix().rotate(180);\r\n imageArrow.animate({transform:rotate, duration:180});\r\n if (refreshCount == 0) {\r\n labelStatus.text = 'Release to get Vegetables...';\r\n } else {\r\n labelStatus.text = 'Release to get Fish...';\r\n }\r\n }\r\n}\r\n\r\nfunction pullendListener(e){\r\n eventStatus.text = 'EVENT pullend FIRED.';\r\n \r\n if (refreshCount == 0) {\r\n labelStatus.text = 'Loading Vegetables...'; \r\n } else {\r\n labelStatus.text = 'Loading Fish...';\r\n }\r\n imageArrow.hide();\r\n actInd.show();\r\n listView.setContentInsets({top:80}, {animated:true});\r\n setTimeout(function(){\r\n loadTableData();\r\n }, 2000);\r\n}\r\n\r\nvar tableHeader = Ti.UI.createView({\r\n backgroundColor:'#e2e7ed',\r\n width:320, height:80\r\n});\r\n\r\nvar border = Ti.UI.createView({\r\n backgroundColor:'#576c89',\r\n bottom:0,\r\n height:2\r\n});\r\ntableHeader.add(border);\r\n\r\nvar imageArrow = Ti.UI.createImageView({\r\n image:'https://github.com/appcelerator/titanium_mobile/raw/master/demos/KitchenSink/Resources/images/whiteArrow.png',\r\n left:20, bottom:10,\r\n width:23, height:60\r\n});\r\ntableHeader.add(imageArrow);\r\n\r\nvar labelStatus = Ti.UI.createLabel({\r\n color:'#576c89',\r\n font:{fontSize:13, fontWeight:'bold'},\r\n text:'Pull down to refresh...',\r\n textAlign:'center',\r\n left:55, bottom:30,\r\n width:200\r\n});\r\ntableHeader.add(labelStatus);\r\n\r\nvar labelLastUpdated = Ti.UI.createLabel({\r\n color:'#576c89',\r\n font:{fontSize:12},\r\n text:'Last Updated: ' + getFormattedDate(),\r\n textAlign:'center',\r\n left:55, bottom:15,\r\n width:200\r\n});\r\ntableHeader.add(labelLastUpdated);\r\n\r\nvar actInd = Ti.UI.createActivityIndicator({\r\n left:20, bottom:13,\r\n width:30, height:30\r\n});\r\ntableHeader.add(actInd);\r\nlistView.pullView = tableHeader;\r\nlistView.addEventListener('pull', pullListener);\r\nlistView.addEventListener('pullend',pullendListener);\r\n\r\nvar eventStatus = Ti.UI.createLabel({\r\n font:{fontSize:13, fontWeight:'bold'},\r\n text: 'Event data will show here',\r\n bottom:0,\r\n height:'10%'\r\n})\r\n\r\nwin.add(listView);\r\nwin.add(eventStatus);\r\nwin.open();\r\n{code}\r\n\r\n\r\n\r\nPull down list view so loading starts. Then, try to scroll list view. You should see that rows are scrolling, but first section view stays fixed (other seems fine).", "attachment": [], "flagged": false, "summary": "ListView - first section doesn't scroll when doing pull to refresh", "creator": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": "* TiSDK 3.2.2.GA & 3.3.0.GA\r\n* iOS 7.1\r\n* TiCLI 3.3.0\r\n* Xcode 5.1.1", "comment": { "comments": [ { "id": "329726", "author": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "More info about this issue:\r\n\r\n\r\nSeems like RefreshControl has the same issue:\r\n\r\n\r\n{code}\r\nvar win = Ti.UI.createWindow({\r\n\ttop: 20\r\n});\r\n\r\nvar counter = 0;\r\n\r\nfunction genData() {\r\n\tvar data = [];\r\n\tvar i=1;\r\n\tfor (i=1;i<=3;i++) {\r\n\t\tdata.push({ properties: { title: 'ROW ' + (counter + i) }})\r\n\t}\r\n\tcounter += 3;\r\n\treturn data;\r\n}\r\n\r\nvar section = Ti.UI.createListSection({ headerTitle: 'Section' });\r\n\r\nsection.setItems(genData());\r\n\r\nvar control = Ti.UI.createRefreshControl({\r\n\ttintColor: 'red'\r\n});\r\n\r\nvar listView = Ti.UI.createListView({\r\n\tsections:[section],\r\n\trefreshControl:control\r\n});\r\n\r\ncontrol.addEventListener('refreshstart',function(e){\r\n\tTi.API.info('refreshstart');\r\n\tsetTimeout(function(){\r\n\t\tTi.API.debug('Timeout');\r\n\t\tsection.appendItems(genData());\r\n\t\tcontrol.endRefreshing();\r\n\t}, 5000);\r\n});\r\n\r\nwin.add(listView);\r\nwin.open();\r\n{code}\r\n\r\nPull to refresh, then scroll up. You'll see the same issue.\r\n\r\n\r\n\r\n\r\nI did some research, seems like the problem is that RefreshControl is being added as table view child:\r\n\r\nhttp://stackoverflow.com/questions/15233147/header-displaced-in-tableview-with-uirefreshcontrol\r\n\r\nhttps://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIListView.m#L636\r\n\r\n\r\nI tried suggested workaround suggested there, basically, commented out: https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIListView.m#L631\r\n\r\nand replaced https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIListView.m#L636 with\r\n\r\n{code}\r\nif (tableController == nil) {\r\n tableController = [[UITableViewController alloc] init];\r\n [TiUtils configureController:tableController withObject:nil];\r\n tableController.tableView = [self tableView];\r\n}\r\ntableController.refreshControl = [_refreshControlProxy control];\r\n{code}\r\n\r\n\r\nand the issue is gone.\r\n\r\n\r\n\r\nI would make pull request, but tbh I'm not iOS developer :) so I'm not sure is solution ok.\r\nIf someone could take a look and see if solution is ok and make changes in Ti repository, that would be great because we would at least have some workaround for this issue.\r\n\r\n\r\n\r\nAlso, original issue may happen because of same reason, but I can't fix it since my Objective-C knowledge is ... limited. :)\r\nBut, I found solution that works: https://github.com/enormego/EGOTableViewPullRefresh If it will help.\r\n\r\n\r\nThanks.", "updateAuthor": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-10-28T10:27:07.000+0000", "updated": "2014-10-28T10:27:07.000+0000" }, { "id": "361703", "author": { "name": "pchowdhury", "key": "pchowdhury", "displayName": "Papia Chowdhury", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Hello,\r\n\r\nI have tested both the user's provided test cases in my environment and observed that pull to refresh works perfectly for me. It is perhaps no longer and issue for you. I will mark this ticket resolved. You can re-open if you have a test case to reproduce it.\r\n\r\n*Testing Environment:*\r\nAppcelerator Studio, build: 4.2.0.201508141038\r\nTitanium SDK: 4.1.0 GA\r\niOS simulator: iphone 5s(v8.1)\r\nOS X version: 10.9.5\r\n\r\n*Steps to Test:*\r\n1. Run below codes on simulator.\r\n2. Pull down listview\r\n3. and try to scroll down\r\n\r\nYou will see that rows are scrolling and list section updates perfectly.\r\n\r\n*Test Case: 1*\r\n{code}\r\nvar win = Ti.UI.createWindow({backgroundColor: 'white', top: 20});\r\nvar listView = Ti.UI.createListView({height:'90%', top:0});\r\nvar sections = [];\r\n \r\nvar fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'});\r\nvar fruitDataSet = [\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Apple'}},\r\n {properties: { title: 'Banana'}},\r\n];\r\nfruitSection.setItems(fruitDataSet);\r\nsections.push(fruitSection);\r\n \r\nvar vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'});\r\nvar vegDataSet = [\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Carrots'}},\r\n {properties: { title: 'Potatoes'}},\r\n];\r\nvegSection.setItems(vegDataSet);\r\n \r\nvar fishSection = Ti.UI.createListSection({ headerTitle: 'Fish'});\r\nvar fishDataSet = [\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Cod'}},\r\n {properties: { title: 'Haddock'}},\r\n];\r\nfishSection.setItems(fishDataSet);\r\nlistView.sections = sections;\r\nvar refreshCount = 0;\r\n \r\nfunction getFormattedDate(){\r\n var date = new Date();\r\n return date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes();\r\n}\r\n \r\nfunction resetPullHeader(){\r\n actInd.hide();\r\n imageArrow.transform=Ti.UI.create2DMatrix();\r\n if (refreshCount < 2) {\r\n imageArrow.show();\r\n labelStatus.text = 'Pull down to refresh...';\r\n labelLastUpdated.text = 'Last Updated: ' + getFormattedDate();\r\n } else {\r\n labelStatus.text = 'Nothing To Refresh';\r\n labelLastUpdated.text = 'Last Updated: ' + getFormattedDate();\r\n listView.removeEventListener('pull', pullListener);\r\n listView.removeEventListener('pullend', pullendListener);\r\n eventStatus.text = 'Removed event listeners.';\r\n }\r\n listView.setContentInsets({top:0}, {animated:true});\r\n}\r\n \r\nfunction loadTableData()\r\n{\r\n if (refreshCount == 0) {\r\n listView.appendSection(vegSection);\r\n } else if (refreshCount == 1) {\r\n listView.appendSection(fishSection);\r\n } \r\n refreshCount ++;\r\n resetPullHeader();\r\n}\r\n \r\nfunction pullListener(e){\r\n eventStatus.text = 'EVENT pull FIRED. e.active = '+e.active;\r\n if (e.active == false) {\r\n var unrotate = Ti.UI.create2DMatrix();\r\n imageArrow.animate({transform:unrotate, duration:180});\r\n labelStatus.text = 'Pull down to refresh...';\r\n } else {\r\n var rotate = Ti.UI.create2DMatrix().rotate(180);\r\n imageArrow.animate({transform:rotate, duration:180});\r\n if (refreshCount == 0) {\r\n labelStatus.text = 'Release to get Vegetables...';\r\n } else {\r\n labelStatus.text = 'Release to get Fish...';\r\n }\r\n }\r\n}\r\n \r\nfunction pullendListener(e){\r\n eventStatus.text = 'EVENT pullend FIRED.';\r\n \r\n if (refreshCount == 0) {\r\n labelStatus.text = 'Loading Vegetables...'; \r\n } else {\r\n labelStatus.text = 'Loading Fish...';\r\n }\r\n imageArrow.hide();\r\n actInd.show();\r\n listView.setContentInsets({top:80}, {animated:true});\r\n setTimeout(function(){\r\n loadTableData();\r\n }, 2000);\r\n}\r\n \r\nvar tableHeader = Ti.UI.createView({\r\n backgroundColor:'#e2e7ed',\r\n width:320, height:80\r\n});\r\n \r\nvar border = Ti.UI.createView({\r\n backgroundColor:'#576c89',\r\n bottom:0,\r\n height:2\r\n});\r\ntableHeader.add(border);\r\n \r\nvar imageArrow = Ti.UI.createImageView({\r\n image:'https://github.com/appcelerator/titanium_mobile/raw/master/demos/KitchenSink/Resources/images/whiteArrow.png',\r\n left:20, bottom:10,\r\n width:23, height:60\r\n});\r\ntableHeader.add(imageArrow);\r\n \r\nvar labelStatus = Ti.UI.createLabel({\r\n color:'#576c89',\r\n font:{fontSize:13, fontWeight:'bold'},\r\n text:'Pull down to refresh...',\r\n textAlign:'center',\r\n left:55, bottom:30,\r\n width:200\r\n});\r\ntableHeader.add(labelStatus);\r\n \r\nvar labelLastUpdated = Ti.UI.createLabel({\r\n color:'#576c89',\r\n font:{fontSize:12},\r\n text:'Last Updated: ' + getFormattedDate(),\r\n textAlign:'center',\r\n left:55, bottom:15,\r\n width:200\r\n});\r\ntableHeader.add(labelLastUpdated);\r\n \r\nvar actInd = Ti.UI.createActivityIndicator({\r\n left:20, bottom:13,\r\n width:30, height:30\r\n});\r\ntableHeader.add(actInd);\r\nlistView.pullView = tableHeader;\r\nlistView.addEventListener('pull', pullListener);\r\nlistView.addEventListener('pullend',pullendListener);\r\n \r\nvar eventStatus = Ti.UI.createLabel({\r\n font:{fontSize:13, fontWeight:'bold'},\r\n text: 'Event data will show here',\r\n bottom:0,\r\n height:'10%'\r\n})\r\n \r\nwin.add(listView);\r\nwin.add(eventStatus);\r\nwin.open();\r\n{code}\r\n\r\n*Test Case: 2*\r\n{code}\r\nvar win = Ti.UI.createWindow({\r\n\ttop: 20\r\n});\r\n \r\nvar counter = 0;\r\n \r\nfunction genData() {\r\n\tvar data = [];\r\n\tvar i=1;\r\n\tfor (i=1;i<=3;i++) {\r\n\t\tdata.push({ properties: { title: 'ROW ' + (counter + i) }})\r\n\t}\r\n\tcounter += 3;\r\n\treturn data;\r\n}\r\n \r\nvar section = Ti.UI.createListSection({ headerTitle: 'Section' });\r\n \r\nsection.setItems(genData());\r\n \r\nvar control = Ti.UI.createRefreshControl({\r\n\ttintColor: 'red'\r\n});\r\n \r\nvar listView = Ti.UI.createListView({\r\n\tsections:[section],\r\n\trefreshControl:control\r\n});\r\n \r\ncontrol.addEventListener('refreshstart',function(e){\r\n\tTi.API.info('refreshstart');\r\n\tsetTimeout(function(){\r\n\t\tTi.API.debug('Timeout');\r\n\t\tsection.appendItems(genData());\r\n\t\tcontrol.endRefreshing();\r\n\t}, 5000);\r\n});\r\n \r\nwin.add(listView);\r\nwin.open();\r\n{code}\r\n\r\nThanks.", "updateAuthor": { "name": "shossain", "key": "shossain", "displayName": "Shak Hossain", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-08-31T06:36:58.000+0000", "updated": "2015-09-02T05:52:18.000+0000" }, { "id": "365881", "author": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Papia Chowdhury, I can still see the issue. Please retest on device.\r\n\r\n\r\nRun your test case, do pull to refresh and while app is refreshing, scroll down. I can see section title still floating and not scrolling properly.\r\nI tested using TiSDK 5.0.2 on iPhone 5s running iOS 9.", "updateAuthor": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-06T10:38:09.000+0000", "updated": "2015-10-06T10:38:09.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }