{ "id": "119320", "key": "TIMOB-15010", "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": "15646", "description": "2013 Sprint 18", "name": "2013 Sprint 18", "archived": true, "released": true, "releaseDate": "2013-09-06" }, { "id": "15690", "description": "2013 Sprint 18 API", "name": "2013 Sprint 18 API", "archived": true, "released": true, "releaseDate": "2013-09-06" } ], "resolution": { "id": "2", "description": "The problem described is an issue which will never be fixed.", "name": "Won't Fix" }, "resolutiondate": "2013-09-16T07:58:01.000+0000", "created": "2013-08-30T16:12:43.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "ios7", "triage" ], "versions": [], "issuelinks": [ { "id": "31899", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "108985", "key": "TIMOB-12618", "fields": { "summary": "iOS: Expose New iOS 6 API UIRefreshControl for TableView 'Pull to Refresh'", "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": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } } ], "assignee": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-21T18:12:07.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": "h2. Description of the problem\r\nHaving a table with search bar and headerPullView, if the search bar is clicked before the header view is disappearing, the search bar overlaps it. The header only disappears after the search bar is blurred.\r\n\r\nh2. Steps to reproduce\r\n1) Use the code below on iPad\r\n2) Pull the table, so that the header will stay (it will disappear in 5s)\r\n3) Click the search bar before the header disappears\r\n\r\n{code}\r\nTitanium.UI.setBackgroundColor('#000');\r\n\r\nvar tabGroup = Titanium.UI.createTabGroup();\r\n\r\nvar win1 = Titanium.UI.createWindow({\r\n\ttitle : 'Table with Search',\r\n\tbackgroundColor : '#fff'\r\n});\r\nvar tab1 = Titanium.UI.createTab({\r\n\ticon : 'KS_nav_views.png',\r\n\ttitle : 'Table w/ Search',\r\n\twindow : win1\r\n});\r\n\r\nvar allNoteTypes = [{\r\n\ttitle : 'Plan 1'\r\n}, {\r\n\ttitle : 'Plan 2'\r\n}, {\r\n\ttitle : 'Plan 3'\r\n}];\r\n\r\nvar refreshView = Ti.UI.createView({\r\n\twidth : \"100%\",\r\n\ttop : 0,\r\n\theight : 22,\r\n\tbackgroundColor : \"#000\"\r\n});\r\n\r\nvar lblRefreshTime = Ti.UI.createLabel({\r\n\tleft : 5,\r\n\twidth : '55%',\r\n\ttext : \"refreshed 1 min ago\"\r\n});\r\n\r\nvar searchBar = Ti.UI.createSearchBar({\r\n\tbarColor : \"#283D5A\",\r\n\tautocorrect : false,\r\n\tautocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,\r\n\thintText : \"SR Number\",\r\n\tkeyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION\r\n});\r\n\r\nvar table = Ti.UI.createTableView({\r\n\ttop : 22,\r\n\twidth : \"100%\",\r\n\tbackgroundColor : 'transparent',\r\n\thideSearchOnSelection : false,\r\n\tdata : allNoteTypes,\r\n\tsearch : searchBar\r\n});\r\n\r\nrefreshView.add(lblRefreshTime);\r\nwin1.add(refreshView);\r\nwin1.add(table);\r\n\r\nvar border = Ti.UI.createView({\r\n\tbackgroundColor : \"#576c89\",\r\n\theight : 2,\r\n\tbottom : 0\r\n});\r\n\r\nvar tableHeader = Ti.UI.createView({\r\n\tbackgroundColor : \"#bcbdc1\",\r\n\twidth : Ti.Platform.displayCaps.platformWidth,\r\n\theight : 60\r\n});\r\n\r\ntableHeader.add(border);\r\n\r\nvar statusLabel = Ti.UI.createLabel({\r\n\ttext : \"Pull to Reload\",\r\n\tleft : 55,\r\n\tbottom : 30,\r\n\theight : \"auto\",\r\n\tcolor : \"#FFF\",\r\n\ttextAlign : \"center\"\r\n});\r\n\r\ntableHeader.add(statusLabel);\r\ntable.headerPullView = tableHeader;\r\n\r\nvar pulling = false;\r\nvar reloading = false;\r\n\r\nfunction beginReloading() {\r\n\tsetTimeout(endReloading, 5000);\r\n}\r\n\r\nfunction endReloading() {\r\n\ttable.setContentInsets({\r\n\t\ttop : 0\r\n\t}, {\r\n\t\tanimated : true\r\n\t});\r\n\treloading = false;\r\n\tstatusLabel.text = \"Pull down to refresh...\";\r\n\t\r\n\ttable.separatorColor = 'transparent';\r\n}\r\n\r\nvar offset = 0;\r\ntable.addEventListener('scroll', function(e) {\r\n\toffset = e.contentOffset.y;\r\n\tif (offset <= -65.0 && !pulling) {\r\n\t\tpulling = true;\r\n\t\tstatusLabel.text = \"Release to refresh...\";\r\n\t} else if (pulling && offset > -65.0 && offset < 0) {\r\n\t\tpulling = false;\r\n\t\tstatusLabel.text = \"Pull down to refresh...\";\r\n\t}\r\n});\r\n\r\ntable.addEventListener('dragEnd', function(e) {\r\n\tif (pulling && !reloading && offset <= -65.0) {\r\n\t\treloading = true;\r\n\t\tpulling = false;\r\n\t\tstatusLabel.text = \"Reloading...\";\r\n\t\ttable.setContentInsets({\r\n\t\t\ttop : 60\r\n\t\t}, {\r\n\t\t\tanimated : true\r\n\t\t});\r\n\t\tbeginReloading();\r\n\t}\r\n});\r\n\r\nfunction handleSearchBarFocus(_event) {\r\n\tendReloading();\r\n}\r\nsearchBar.addEventListener(\"click\", handleSearchBarFocus);\r\n\r\ntabGroup.addTab(tab1);\r\ntabGroup.open();\r\n{code}\r\n\r\nh2. Results\r\nBoth on iOS6 and iOS7 the header does not disappear (although endReloading is called); however, on iOS7 the search bar goes up and overlaps the header. See screenshots.", "attachment": [ { "id": "42023", "filename": "iOS6PullRefresh.png", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-08-30T16:17:46.000+0000", "size": 223895, "mimeType": "image/png" }, { "id": "42024", "filename": "iOS7PullRefresh.png", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-08-30T16:17:46.000+0000", "size": 246243, "mimeType": "image/png" } ], "flagged": false, "summary": "iOS7: Table pull to refresh does not behave as iOS6 when using a search bar in the table", "creator": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "environment": "SDK 3.1.2\r\niOS7 beta 6", "comment": { "comments": [ { "id": "269044", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~dcassenti] Can you please test this with the latest 3.1.X CI to confirm the issue still exists?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-30T16:17:11.000+0000", "updated": "2013-08-30T16:17:11.000+0000" }, { "id": "269049", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "[~ingo] Same behavior with 3.1.3 just downloaded.", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-08-30T16:25:59.000+0000", "updated": "2013-08-30T16:25:59.000+0000" }, { "id": "269420", "author": { "name": "sghosh", "key": "sghosh", "displayName": "Sid Ghosh", "active": true, "timeZone": "America/New_York" }, "body": "Any update on this issue ?\n\nSid", "updateAuthor": { "name": "sghosh", "key": "sghosh", "displayName": "Sid Ghosh", "active": true, "timeZone": "America/New_York" }, "created": "2013-09-04T01:19:52.000+0000", "updated": "2013-09-04T01:19:52.000+0000" }, { "id": "269515", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "SearchView is being added on top of the TableView. One suggestion is to hide the search bar when the pull to refresh is happening. We may not be able to fix this for 3.1.3.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-04T18:06:10.000+0000", "updated": "2013-09-04T18:06:10.000+0000" }, { "id": "269635", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Won't Fix. \r\nUse the workaround provided below.\r\n{code}\r\nTitanium.UI.setBackgroundColor('#000');\r\n \r\nvar tabGroup = Titanium.UI.createTabGroup();\r\n \r\nvar win1 = Titanium.UI.createWindow({\r\n title : 'Table with Search',\r\n backgroundColor : '#fff'\r\n});\r\nvar tab1 = Titanium.UI.createTab({\r\n icon : 'KS_nav_views.png',\r\n title : 'Table w/ Search',\r\n window : win1\r\n});\r\n \r\nvar allNoteTypes = [{\r\n title : 'Plan 1'\r\n}, {\r\n title : 'Plan 2'\r\n}, {\r\n title : 'Plan 3'\r\n}];\r\n \r\nvar refreshView = Ti.UI.createView({\r\n width : \"100%\",\r\n top : 0,\r\n height : 22,\r\n backgroundColor : \"#000\"\r\n});\r\n \r\nvar lblRefreshTime = Ti.UI.createLabel({\r\n left : 5,\r\n width : '55%',\r\n text : \"refreshed 1 min ago\"\r\n});\r\n \r\nvar searchBar = Ti.UI.createSearchBar({\r\n barColor : \"#283D5A\",\r\n autocorrect : false,\r\n autocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,\r\n hintText : \"SR Number\",\r\n keyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION\r\n});\r\n \r\nvar table = Ti.UI.createTableView({\r\n top : 22,\r\n width : \"100%\",\r\n backgroundColor : 'transparent',\r\n hideSearchOnSelection : false,\r\n data : allNoteTypes,\r\n search : searchBar\r\n});\r\n \r\nrefreshView.add(lblRefreshTime);\r\nwin1.add(refreshView);\r\nwin1.add(table);\r\n \r\nvar border = Ti.UI.createView({\r\n backgroundColor : \"#576c89\",\r\n height : 2,\r\n bottom : 0\r\n});\r\n \r\nvar tableHeader = Ti.UI.createView({\r\n backgroundColor : \"#bcbdc1\",\r\n width : Ti.Platform.displayCaps.platformWidth,\r\n height : 60\r\n});\r\n \r\ntableHeader.add(border);\r\n \r\nvar statusLabel = Ti.UI.createLabel({\r\n text : \"Pull to Reload\",\r\n left : 55,\r\n bottom : 30,\r\n height : \"auto\",\r\n color : \"#FFF\",\r\n textAlign : \"center\"\r\n});\r\n \r\ntableHeader.add(statusLabel);\r\ntable.headerPullView = tableHeader;\r\n \r\nvar pulling = false;\r\nvar reloading = false;\r\n\r\nvar overlay = Ti.UI.createView({\r\n opacity:.2,\r\n backgroundColor:'black'\r\n})\r\n\r\nfunction beginReloading() {\r\n searchBar.add(overlay);\r\n setTimeout(endReloading, 5000);\r\n}\r\n \r\nfunction endReloading() {\r\n searchBar.remove(overlay);\r\n table.setContentInsets({\r\n top : 0\r\n }, {\r\n animated : true\r\n });\r\n reloading = false;\r\n statusLabel.text = \"Pull down to refresh...\";\r\n \r\n table.separatorColor = 'transparent';\r\n}\r\n \r\nvar offset = 0;\r\ntable.addEventListener('scroll', function(e) {\r\n offset = e.contentOffset.y;\r\n if (offset <= -65.0 && !pulling) {\r\n pulling = true;\r\n statusLabel.text = \"Release to refresh...\";\r\n } else if (pulling && offset > -65.0 && offset < 0) {\r\n pulling = false;\r\n statusLabel.text = \"Pull down to refresh...\";\r\n }\r\n});\r\n \r\ntable.addEventListener('dragEnd', function(e) {\r\n if (pulling && !reloading && offset <= -65.0) {\r\n reloading = true;\r\n pulling = false;\r\n statusLabel.text = \"Reloading...\";\r\n table.setContentInsets({\r\n top : 60\r\n }, {\r\n animated : true\r\n });\r\n beginReloading();\r\n }\r\n});\r\n\r\nfunction handleSearchBarFocus(_event){\r\n endReloading();\r\n setTimeout(function(){\r\n searchBar.focus();\r\n },300)\r\n}\r\n \r\n\r\noverlay.addEventListener(\"click\", handleSearchBarFocus);\r\n \r\ntabGroup.addTab(tab1);\r\ntabGroup.open();\r\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-09-04T23:38:02.000+0000", "updated": "2013-09-04T23:38:02.000+0000" }, { "id": "269678", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "The solution proposed by [~vduggal] is not working if you reload more than once; steps:\r\n\r\n1) pull down to refresh\r\n2) click on the overlay (it works)\r\n3) click to hide the search\r\n4) repeat step 1: overlay is not added anymore\r\n\r\nI tried also to re-create the overlay each time: same result. I also tried the suggestion by [~ingo], and if I show/hide the search bar directly, it is not working as well.\r\n\r\nThese are the solutions tested:\r\n\r\nh3. Solution 1\r\nHide the bar using searchBar. The search bar is only hidden the first time.\r\n\r\n{code}\r\nfunction beginReloading() {\r\n searchBar.hide(); // ONLY WORKS FIRST TIME\r\n reloadingTimeout = setTimeout(endReloading, 5000);\r\n}\r\n{code}\r\n\r\nh3. Solution 2\r\nI tried changing searchBar.hide() with table.search.hide() and it works:\r\n\r\n{code}\r\nfunction beginReloading() {\r\n table.search.hide(); // WORKS FINE\r\n reloadingTimeout = setTimeout(endReloading, 5000);\r\n}\r\n{code}\r\n\r\nh3. Solution 3\r\nI tried to use table.search in combination with the add/remove overlay, but again no luck.\r\n\r\n{code}\r\nfunction beginReloading() {\r\n table.search.add(overlay); // ONLY WORKS FIRST TIME\r\n reloadingTimeout = setTimeout(endReloading, 5000);\r\n}\r\n{code}\r\n\r\nh3. Notes\r\nI proposed solution 2 to the customer, waiting feedback.", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-09-05T10:11:32.000+0000", "updated": "2013-09-05T10:12:17.000+0000" }, { "id": "271091", "author": { "name": "sghosh", "key": "sghosh", "displayName": "Sid Ghosh", "active": true, "timeZone": "America/New_York" }, "body": "Vishal \n\nAny update on this issue?\n\nSid", "updateAuthor": { "name": "sghosh", "key": "sghosh", "displayName": "Sid Ghosh", "active": true, "timeZone": "America/New_York" }, "created": "2013-09-13T19:28:10.000+0000", "updated": "2013-09-13T19:28:10.000+0000" }, { "id": "271201", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~sghosh],[~dcassenti]\nThis seems to be a limitation of our current implementation of the search property of tableView (The search field is associated with the tableView and the searchController). While this design has worked on previous versions of iOS, iOS 7 seems to have broken it. Fixing it would require a significant rewrite of our tableView (and by the looks of if ListView, though ListView has the new searchText API which is a much better alternative)\n\nCurrently the only solution for the current problem would be to disable scrolling in beginReloading (table.scrollable = false) and re-enable it in endReloading(table.scrollable = true). Sample code attached.\n{code}\nTitanium.UI.setBackgroundColor('#000');\n \nvar tabGroup = Titanium.UI.createTabGroup();\n \nvar win1 = Titanium.UI.createWindow({\n title : 'Table with Search',\n backgroundColor : '#fff'\n});\nvar tab1 = Titanium.UI.createTab({\n icon : 'KS_nav_views.png',\n title : 'Table w/ Search',\n window : win1\n});\n \nvar allNoteTypes = [{\n title : 'Plan 1'\n}, {\n title : 'Plan 2'\n}, {\n title : 'Plan 3'\n}];\n \nvar refreshView = Ti.UI.createView({\n width : \"100%\",\n top : 0,\n height : 22,\n backgroundColor : \"#000\"\n});\n \nvar lblRefreshTime = Ti.UI.createLabel({\n left : 5,\n width : '55%',\n text : \"refreshed 1 min ago\"\n});\n \nvar searchBar = Ti.UI.createSearchBar({\n barColor : \"#283D5A\",\n autocorrect : false,\n autocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,\n hintText : \"SR Number\",\n keyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION\n});\n \nvar table = Ti.UI.createTableView({\n top : 22,\n width : \"100%\",\n backgroundColor : 'transparent',\n hideSearchOnSelection : false,\n data : allNoteTypes,\n search : searchBar\n});\n \nrefreshView.add(lblRefreshTime);\nwin1.add(refreshView);\nwin1.add(table);\n \nvar border = Ti.UI.createView({\n backgroundColor : \"#576c89\",\n height : 2,\n bottom : 0\n});\n \nvar tableHeader = Ti.UI.createView({\n backgroundColor : \"#bcbdc1\",\n width : Ti.Platform.displayCaps.platformWidth,\n height : 60\n});\n \ntableHeader.add(border);\n \nvar statusLabel = Ti.UI.createLabel({\n text : \"Pull to Reload\",\n left : 55,\n bottom : 30,\n height : \"auto\",\n color : \"#FFF\",\n textAlign : \"center\"\n});\n \ntableHeader.add(statusLabel);\ntable.headerPullView = tableHeader;\n \nvar pulling = false;\nvar reloading = false;\n \nvar overlay = Ti.UI.createView({\n opacity:.2,\n backgroundColor:'black'\n})\n \nvar timeOutCounter;\n \nfunction beginReloading() {\n searchBar.add(overlay);\n table.scrollable = false;\n timeOutCounter = setTimeout(function(){\n Ti.API.info('TIMEOUT');\n endReloading();\n },5000);\n Ti.API.info('setTimeout returned '+timeOutCounter);\n}\n \nfunction endReloading() {\n Ti.API.info('END Reloading called. Current Counter '+timeOutCounter);\n clearTimeout(timeOutCounter);\n searchBar.remove(overlay);\n table.scrollable = true;\n table.setContentInsets({\n top : 0\n }, {\n animated : true\n });\n reloading = false;\n statusLabel.text = \"Pull down to refresh...\";\n}\n \nvar offset = 0;\ntable.addEventListener('scroll', function(e) {\n if (reloading) {\n return;\n }\n offset = e.contentOffset.y;\n if (offset <= -65.0 && !pulling) {\n pulling = true;\n statusLabel.text = \"Release to refresh...\";\n } else if (pulling && offset > -65.0 && offset < 0) {\n pulling = false;\n statusLabel.text = \"Pull down to refresh...\";\n }\n});\n \ntable.addEventListener('dragEnd', function(e) {\n if (reloading) {\n return;\n }\n if (pulling && !reloading && offset <= -65.0) {\n reloading = true;\n pulling = false;\n statusLabel.text = \"Reloading...\";\n table.setContentInsets({\n top : 60\n }, {\n animated : true\n });\n beginReloading();\n }\n});\n \nfunction handleSearchBarFocus(_event){\n Ti.API.info('FOCUS');\n endReloading();\n setTimeout(function(){\n searchBar.focus();\n },300)\n}\n \n \noverlay.addEventListener(\"click\", handleSearchBarFocus);\n \ntabGroup.addTab(tab1);\ntabGroup.open();\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-09-16T07:53:32.000+0000", "updated": "2013-09-16T07:53:32.000+0000" }, { "id": "271202", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Marking this as Won't Fix although this obviously shows a limitation of our current implementation of our built in search functionality. \r\n\r\nThis should be resolved with the refresh Control ticket [TIMOB-12618] when we move to UITableViewController instead of a plain tableView.", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-09-16T07:58:01.000+0000", "updated": "2013-09-16T07:58:01.000+0000" }, { "id": "414257", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as the issue will not fix.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-21T18:12:07.000+0000", "updated": "2017-03-21T18:12:07.000+0000" } ], "maxResults": 15, "total": 15, "startAt": 0 } } }