{ "id": "106036", "key": "TIMOB-11973", "fields": { "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": "14162", "description": "Release 3.1.0", "name": "Release 3.1.0", "archived": true, "released": true, "releaseDate": "2013-04-16" }, { "id": "14700", "description": "2012 Sprint 25", "name": "2012 Sprint 25", "archived": true, "released": true, "releaseDate": "2012-12-17" }, { "id": "14784", "description": "2012 Sprint 25 API", "name": "2012 Sprint 25 API", "archived": true, "released": true, "releaseDate": "2012-12-17" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2012-12-06T23:06:56.000+0000", "created": "2012-12-06T00:32:36.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "SupportTeam" ], "versions": [ { "id": "14613", "description": "Release 2.1.4", "name": "Release 2.1.4", "archived": true, "released": true, "releaseDate": "2012-11-12" }, { "id": "14162", "description": "Release 3.1.0", "name": "Release 3.1.0", "archived": true, "released": true, "releaseDate": "2013-04-16" } ], "issuelinks": [], "assignee": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2014-06-19T12:42:54.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": "h6.Issue\r\nNot able to longer scroll the tableView all the way to the bottom, when attempt animating the 'top' value of a tableView, causes it the contentView to stop scrolling correctly on iOS.\r\n\r\nh6.Reproducible steps\r\n * 1. Start the app! :)\r\n * 2. Scroll the tableView up/down to make sure that all rows are visible\r\n * 3. Click on the blue bar (Where it says 'Click me!')\r\n * 4. Attempt to scroll the tableView all the way to the bottom\r\n * 5. Click on the blue bar \r\n * 6. Attempt to scroll the tableView (after it is now in its original state)\r\n\r\nThis happens after step 4, and then step 6 will return the table to its original state, where you are still unable to scroll to the bottom.\r\n\r\nh6.Expected\r\nScroll tableView as needed\r\n\r\nh6.Actual\r\nYou can scroll the entire tableView, only once, when actually the application is first launched.\r\n\r\nh6.Tested on\r\niOS 6 simulator\r\niPhone 4 - iOS 6\r\n\r\nh6.Console output\r\n[WARN] New layout set while view [object TiUITableView] animating: Will relayout after animation.\r\n\r\nh6.Runnable sample\r\n{code}\r\nvar platformHeight = Ti.Platform.displayCaps.platformHeight - 20, //status bar\r\n\tplatformWidth = Ti.Platform.displayCaps.platformWidth;\r\n\r\nvar fullsizeContainer = Ti.UI.createAnimation({height: platformHeight, duration: 300}); \r\nvar halfsizeContainer = Ti.UI.createAnimation({height: platformHeight/2, duration: 300})\r\n\r\nvar showGreenBar = Ti.UI.createAnimation({top: 60, duration: 300}); \r\nvar hideGreenBar = Ti.UI.createAnimation({top: 20, duration: 300});\r\n\r\nvar TABLESTATE = {half: 1, full: 2};\r\n\r\n(function() {\r\n\t\r\n\tvar appWindow = Ti.UI.createWindow({\r\n\t\tbackgroundColor:'white'\r\n\t});\r\n\t\r\n\tvar container = Ti.UI.createView({\r\n\t\tbackgroundColor: 'white',\r\n\t\theight: platformHeight/2,\r\n\t\twidth: platformWidth,\r\n\t\tbottom: 0\r\n\t});\r\n\t\r\n\tvar blueBar = Ti.UI.createLabel({\r\n\t\tbackgroundColor: 'blue',\r\n\t\ttext: \"Click Me!\",\r\n\t\tcolor: 'white',\r\n\t\twidth: platformWidth,\r\n\t\theight: 20,\r\n\t\ttop: 0,\r\n\t\ttextAlign: Ti.UI.TEXT_ALIGNMENT_CENTER, \r\n\t\tborderColor: 'black' //for aesthetics \r\n\t});\r\n\t\r\n\tvar greenBar = Ti.UI.createView({\r\n\t\tbackgroundColor: 'green',\r\n\t\twidth: platformWidth,\r\n\t\theight: 40,\r\n\t\ttop: 20\r\n\t});\r\n\t\r\n\tvar tableData = [];\r\n\r\n\tvar sectionOne = Ti.UI.createTableViewSection({\r\n\t\theaderTitle: \"Section One\"\r\n\t});\r\n\t\r\n\tvar sectionTwo = Ti.UI.createTableViewSection({\r\n\t\theaderTitle: \"Section Two\"\r\n\t});\r\n\t\r\n\tfor(var i = 0; i < 20; i++){\r\n\t\t\r\n\t\tvar row = Ti.UI.createTableViewRow({\r\n\t\t\ttitle: \"Example Row\"\r\n\t\t});\r\n\t\t\r\n\t\tif(i%2){\r\n\t\t\tsectionOne.add(row);\r\n\t\t} else {\r\n\t\t\tsectionTwo.add(row);\r\n\t\t}\r\n\t}\r\n\t\r\n\ttableData.push(sectionOne);\r\n\ttableData.push(sectionTwo);\r\n\t\r\n\tvar tableView = Ti.UI.createTableView({\r\n\t\tbackgroundColor: 'white',\r\n\t\theight: Ti.UI.FILL,\r\n\t\twidth: platformWidth,\r\n\t\ttop: 20,\r\n\t\tdata: tableData,\r\n\t\tborderColor: 'red'\r\n\t});\r\n\t\r\n\tvar tableState = TABLESTATE.half;\r\n\tblueBar.addEventListener('click', function(e){\r\n\t\t\r\n\t\tif(tableState === TABLESTATE.half){\r\n\t\t\t//goes from half --> full\r\n\t\t\tcontainer.animate(fullsizeContainer);\r\n\t\t\ttableView.animate(showGreenBar);\r\n\t\t\ttableState = TABLESTATE.full;\r\n\t\t} else {\r\n\t\t\t//goes from full --> half\r\n\t\t\ttableView.animate(hideGreenBar);\r\n\t\t\tcontainer.animate(halfsizeContainer);\r\n\t\t\ttableState = TABLESTATE.half;\t\r\n\t\t}\r\n\t});\r\n\t\r\n\t\r\n\tcontainer.add(blueBar);\r\n\tcontainer.add(greenBar);\r\n\tcontainer.add(tableView);\r\n\t\r\n\tappWindow.add(container);\r\n\t\r\n\tappWindow.open();\r\n\t\r\n})();\r\n{code}", "attachment": [ { "id": "34094", "filename": "NativeSample.mov (iPod & iPhone).m4v", "author": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T02:29:01.000+0000", "size": 1771470, "mimeType": "video/mp4" }, { "id": "34091", "filename": "TableViewTest.zip", "author": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T02:29:01.000+0000", "size": 28835, "mimeType": "application/zip" }, { "id": "34092", "filename": "TitaniumSample_1.mov (iPod & iPhone) 2.m4v", "author": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T02:29:01.000+0000", "size": 1335642, "mimeType": "video/mp4" }, { "id": "34093", "filename": "TitaniumSample_2.mov (iPod & iPhone) 2.m4v", "author": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T02:29:01.000+0000", "size": 1154298, "mimeType": "video/mp4" } ], "flagged": false, "summary": "iOS: Animating 'top' value of UITableView causes it stop scrolling", "creator": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "Ti SDK 2.1.4.GA & 3.1\r\niOS 6", "comment": { "comments": [ { "id": "230328", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "iOS does not support nesting animations. Need to run animations one after the other. Use sample code below\n{code}\nvar platformHeight = Ti.Platform.displayCaps.platformHeight - 20, //status bar\n platformWidth = Ti.Platform.displayCaps.platformWidth;\n \nvar fullsizeContainer = Ti.UI.createAnimation({height: platformHeight, duration: 300}); \nvar halfsizeContainer = Ti.UI.createAnimation({height: platformHeight/2, duration: 300})\n \nvar showGreenBar = Ti.UI.createAnimation({top: 60, duration: 300}); \nvar hideGreenBar = Ti.UI.createAnimation({top: 20, duration: 300});\n\n \nvar TABLESTATE = {half: 1, full: 2};\n \n(function() {\n \n var appWindow = Ti.UI.createWindow({\n backgroundColor:'white'\n });\n \n var container = Ti.UI.createView({\n backgroundColor: 'white',\n height: platformHeight/2,\n width: platformWidth,\n bottom: 0\n });\n \n var blueBar = Ti.UI.createLabel({\n backgroundColor: 'blue',\n text: \"Click Me!\",\n color: 'white',\n width: platformWidth,\n height: 20,\n top: 0,\n textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER, \n borderColor: 'black' //for aesthetics \n });\n \n var greenBar = Ti.UI.createView({\n backgroundColor: 'green',\n width: platformWidth,\n height: 40,\n top: 20\n });\n \n var tableData = [];\n \n var sectionOne = Ti.UI.createTableViewSection({\n headerTitle: \"Section One\"\n });\n \n var sectionTwo = Ti.UI.createTableViewSection({\n headerTitle: \"Section Two\"\n });\n \n for(var i = 0; i < 20; i++){\n \n var row = Ti.UI.createTableViewRow({\n title: \"Example Row \"+i\n });\n \n if(i%2){\n sectionOne.add(row);\n } else {\n sectionTwo.add(row);\n }\n }\n \n tableData.push(sectionOne);\n tableData.push(sectionTwo);\n \n var tableView = Ti.UI.createTableView({\n backgroundColor: 'white',\n height: Ti.UI.FILL,\n width: platformWidth,\n top: 20,\n data: tableData,\n borderColor: 'red'\n });\n \n\tvar fullsizeHandler = function() {\n \t\tfullsizeContainer.removeEventListener('complete',fullsizeHandler);\n \t\ttableView.animate(showGreenBar);\n\t};\n\t\n\tvar halfsizeHandler = function() {\n \t\thalfsizeContainer.removeEventListener('complete',halfsizeHandler);\n \t\ttableView.animate(hideGreenBar);\n\t};\n\n\tvar tableState = TABLESTATE.half;\n blueBar.addEventListener('click', function(e){\n \n if(tableState === TABLESTATE.half){\n //goes from half --> full\n fullsizeContainer.addEventListener('complete',fullsizeHandler);\n container.animate(fullsizeContainer);\n tableState = TABLESTATE.full;\n } else {\n //goes from full --> half\n halfsizeContainer.addEventListener('complete',halfsizeHandler);\n container.animate(halfsizeContainer);\n tableState = TABLESTATE.half; \n }\n });\n \n \n container.add(blueBar);\n container.add(greenBar);\n container.add(tableView);\n \n appWindow.add(container);\n \n appWindow.open();\n \n})();\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-06T23:06:23.000+0000", "updated": "2012-12-06T23:06:23.000+0000" }, { "id": "231005", "author": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Understood, the 'Complete' event listener fixes the TableView scrolling issue however animation its not quite the look the developer was attempting to make with those animations.\r\n\r\nAttaching a native sample that performs the nested Animation:\r\n\r\nh6.Attached files\r\n\r\n- *TableViewTest.zip* native sample project\r\n_Animation block_ in ContainerViewController.m\r\n{code}\r\n- (void) toggleTable {\r\n \r\n if(half){\r\n \r\n [UIView beginAnimations:@\"animateFull\" context:nil];\r\n [UIView setAnimationDuration:0.2];\r\n [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];\r\n \r\n [[containerView view] setFrame:CGRectMake(0, 0, 320, [[UIScreen mainScreen] bounds].size.height)];\r\n [blueButton setFrame:CGRectMake(0, 0, 320, 20)];\r\n [greenBar setFrame:CGRectMake(0, 20, 320, 60)];\r\n [[tableViewController tableView] setFrame:CGRectMake(0, 80, 320, [[UIScreen mainScreen] bounds].size.height - 80)];\r\n \r\n [UIView commitAnimations];\r\n \r\n half = false;\r\n \r\n } else {\r\n\r\n [UIView beginAnimations:@\"animateHalf\" context:nil];\r\n [UIView setAnimationDuration:0.2];\r\n [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];\r\n \r\n [[containerView view] setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2, 320, [[UIScreen mainScreen] bounds].size.height/2)];\r\n [blueButton setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2 - 20, 320, 20)];\r\n [greenBar setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2 + 20, 320, 60)];\r\n [[tableViewController tableView] setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2, 320, [[UIScreen mainScreen] bounds].size.height/2 -20)];\r\n \r\n [UIView commitAnimations];\r\n \r\n // [[containerView view] bringSubviewToFront:[tableViewController tableView]];\r\n half = true;\r\n }\r\n}\r\n{code}\r\n\r\nh6.Attached videos\r\n- *TitaniumSample_1.mov (iPod & iPhone) 2.m4v* This is the result where animations are nested, a minimum test case was posted (without 'complete' event listener). See how Warnings are being thrown then tableView stops scrolling.\r\n\r\n- *TitaniumSample_2.mov (iPod & iPhone) 2.m4v* Result after adding a 'Complete' event listener. Fixes the scrolling issue however animates it different.\r\n\r\n- *NativeSample.mov (iPod & iPhone).m4v* Result of running a native sample where animations worked nested. Have the look the developer attempts to do. ", "updateAuthor": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T02:29:01.000+0000", "updated": "2012-12-12T02:29:01.000+0000" }, { "id": "231049", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "The native code is running a single animation within which two views are animated. The Titanium code is running two animations. Right now we do not support animating two views within a single animation. You can fake it by running the subview animation before the parent view animation and giving the subview view animation a extra time. Try this code instead\n{code}\nvar platformHeight = Ti.Platform.displayCaps.platformHeight - 20, //status bar\n platformWidth = Ti.Platform.displayCaps.platformWidth;\n\n\nvar fullsizeContainer = Ti.UI.createAnimation({height: platformHeight, duration: 200}); \nvar halfsizeContainer = Ti.UI.createAnimation({height: platformHeight/2, duration: 200})\n\n//Give the tableview animations a extra time to complete (x5) \n//why so much? To compensate for JS bridge and layout engine delays\nvar showGreenBar = Ti.UI.createAnimation({top: 60, duration: 1000}); \nvar hideGreenBar = Ti.UI.createAnimation({top: 20, duration: 1000});\n \nvar TABLESTATE = {half: 1, full: 2};\n \n(function() {\n \n var appWindow = Ti.UI.createWindow({\n backgroundColor:'white'\n });\n \n var container = Ti.UI.createView({\n backgroundColor: 'white',\n height: platformHeight/2,\n width: platformWidth,\n bottom: 0\n });\n \n var blueBar = Ti.UI.createLabel({\n backgroundColor: 'blue',\n text: \"Click Me!\",\n color: 'white',\n width: platformWidth,\n height: 20,\n top: 0,\n textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER, \n borderColor: 'black' //for aesthetics \n });\n \n var greenBar = Ti.UI.createView({\n backgroundColor: 'green',\n width: platformWidth,\n height: 40,\n top: 20\n });\n \n var tableData = [];\n \n var sectionOne = Ti.UI.createTableViewSection({\n headerTitle: \"Section One\"\n });\n \n var sectionTwo = Ti.UI.createTableViewSection({\n headerTitle: \"Section Two\"\n });\n \n for(var i = 0; i < 20; i++){\n \n var row = Ti.UI.createTableViewRow({\n title: \"Example Row \"+i\n });\n \n if(i%2){\n sectionOne.add(row);\n } else {\n sectionTwo.add(row);\n }\n }\n \n tableData.push(sectionOne);\n tableData.push(sectionTwo);\n \n var tableView = Ti.UI.createTableView({\n backgroundColor: 'white',\n height: Ti.UI.FILL,\n width: platformWidth,\n top: 20,\n data: tableData,\n borderColor: 'red'\n });\n \n var tableState = TABLESTATE.half;\n blueBar.addEventListener('click', function(e){\n //Run tableView animation before the container animation. \n if(tableState === TABLESTATE.half){\n //goes from half --> full\n tableView.animate(showGreenBar);\n container.animate(fullsizeContainer);\n tableState = TABLESTATE.full;\n } else {\n //goes from full --> half\n tableView.animate(hideGreenBar);\n container.animate(halfsizeContainer);\n tableState = TABLESTATE.half; \n }\n });\n \n \n container.add(blueBar);\n container.add(greenBar);\n container.add(tableView);\n \n appWindow.add(container);\n \n appWindow.open();\n \n})();\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-12T18:16:03.000+0000", "updated": "2012-12-12T18:16:03.000+0000" }, { "id": "235312", "author": { "name": "pmishra", "key": "pmishra", "displayName": "Paras Mishra", "active": true, "timeZone": "Asia/Kolkata" }, "body": "tableView is scrollable.\r\n\r\nVerified on : \r\niPhone 5, iOS 6\r\nSDK version: 3.1.0.v20130111163212\r\nCLI version : 3.0.23\r\nOS : MAC OSX 10.7.5\r\nXCode : 4.5.1", "updateAuthor": { "name": "pmishra", "key": "pmishra", "displayName": "Paras Mishra", "active": true, "timeZone": "Asia/Kolkata" }, "created": "2013-01-22T08:49:12.000+0000", "updated": "2013-01-22T08:49:12.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }