Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-15010] iOS7: Table pull to refresh does not behave as iOS6 when using a search bar in the table

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionWon't Fix
Resolution Date2013-09-16T07:58:01.000+0000
Affected Version/sn/a
Fix Version/s2013 Sprint 18, 2013 Sprint 18 API
ComponentsiOS
Labelsios7, triage
ReporterDavide Cassenti
AssigneeVishal Duggal
Created2013-08-30T16:12:43.000+0000
Updated2017-03-21T18:12:07.000+0000

Description

Description of the problem

Having 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.

Steps to reproduce

1) Use the code below on iPad 2) Pull the table, so that the header will stay (it will disappear in 5s) 3) Click the search bar before the header disappears
Titanium.UI.setBackgroundColor('#000');

var tabGroup = Titanium.UI.createTabGroup();

var win1 = Titanium.UI.createWindow({
	title : 'Table with Search',
	backgroundColor : '#fff'
});
var tab1 = Titanium.UI.createTab({
	icon : 'KS_nav_views.png',
	title : 'Table w/ Search',
	window : win1
});

var allNoteTypes = [{
	title : 'Plan 1'
}, {
	title : 'Plan 2'
}, {
	title : 'Plan 3'
}];

var refreshView = Ti.UI.createView({
	width : "100%",
	top : 0,
	height : 22,
	backgroundColor : "#000"
});

var lblRefreshTime = Ti.UI.createLabel({
	left : 5,
	width : '55%',
	text : "refreshed 1 min ago"
});

var searchBar = Ti.UI.createSearchBar({
	barColor : "#283D5A",
	autocorrect : false,
	autocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,
	hintText : "SR Number",
	keyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION
});

var table = Ti.UI.createTableView({
	top : 22,
	width : "100%",
	backgroundColor : 'transparent',
	hideSearchOnSelection : false,
	data : allNoteTypes,
	search : searchBar
});

refreshView.add(lblRefreshTime);
win1.add(refreshView);
win1.add(table);

var border = Ti.UI.createView({
	backgroundColor : "#576c89",
	height : 2,
	bottom : 0
});

var tableHeader = Ti.UI.createView({
	backgroundColor : "#bcbdc1",
	width : Ti.Platform.displayCaps.platformWidth,
	height : 60
});

tableHeader.add(border);

var statusLabel = Ti.UI.createLabel({
	text : "Pull to Reload",
	left : 55,
	bottom : 30,
	height : "auto",
	color : "#FFF",
	textAlign : "center"
});

tableHeader.add(statusLabel);
table.headerPullView = tableHeader;

var pulling = false;
var reloading = false;

function beginReloading() {
	setTimeout(endReloading, 5000);
}

function endReloading() {
	table.setContentInsets({
		top : 0
	}, {
		animated : true
	});
	reloading = false;
	statusLabel.text = "Pull down to refresh...";
	
	table.separatorColor = 'transparent';
}

var offset = 0;
table.addEventListener('scroll', function(e) {
	offset = e.contentOffset.y;
	if (offset <= -65.0 && !pulling) {
		pulling = true;
		statusLabel.text = "Release to refresh...";
	} else if (pulling && offset > -65.0 && offset < 0) {
		pulling = false;
		statusLabel.text = "Pull down to refresh...";
	}
});

table.addEventListener('dragEnd', function(e) {
	if (pulling && !reloading && offset <= -65.0) {
		reloading = true;
		pulling = false;
		statusLabel.text = "Reloading...";
		table.setContentInsets({
			top : 60
		}, {
			animated : true
		});
		beginReloading();
	}
});

function handleSearchBarFocus(_event) {
	endReloading();
}
searchBar.addEventListener("click", handleSearchBarFocus);

tabGroup.addTab(tab1);
tabGroup.open();

Results

Both 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.

Attachments

FileDateSize
iOS6PullRefresh.png2013-08-30T16:17:46.000+0000223895
iOS7PullRefresh.png2013-08-30T16:17:46.000+0000246243

Comments

  1. Ingo Muschenetz 2013-08-30

    [~dcassenti] Can you please test this with the latest 3.1.X CI to confirm the issue still exists?
  2. Davide Cassenti 2013-08-30

    [~ingo] Same behavior with 3.1.3 just downloaded.
  3. Sid Ghosh 2013-09-04

    Any update on this issue ? Sid
  4. Ingo Muschenetz 2013-09-04

    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.
  5. Vishal Duggal 2013-09-04

    Won't Fix. Use the workaround provided below.
       Titanium.UI.setBackgroundColor('#000');
        
       var tabGroup = Titanium.UI.createTabGroup();
        
       var win1 = Titanium.UI.createWindow({
           title : 'Table with Search',
           backgroundColor : '#fff'
       });
       var tab1 = Titanium.UI.createTab({
           icon : 'KS_nav_views.png',
           title : 'Table w/ Search',
           window : win1
       });
        
       var allNoteTypes = [{
           title : 'Plan 1'
       }, {
           title : 'Plan 2'
       }, {
           title : 'Plan 3'
       }];
        
       var refreshView = Ti.UI.createView({
           width : "100%",
           top : 0,
           height : 22,
           backgroundColor : "#000"
       });
        
       var lblRefreshTime = Ti.UI.createLabel({
           left : 5,
           width : '55%',
           text : "refreshed 1 min ago"
       });
        
       var searchBar = Ti.UI.createSearchBar({
           barColor : "#283D5A",
           autocorrect : false,
           autocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,
           hintText : "SR Number",
           keyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION
       });
        
       var table = Ti.UI.createTableView({
           top : 22,
           width : "100%",
           backgroundColor : 'transparent',
           hideSearchOnSelection : false,
           data : allNoteTypes,
           search : searchBar
       });
        
       refreshView.add(lblRefreshTime);
       win1.add(refreshView);
       win1.add(table);
        
       var border = Ti.UI.createView({
           backgroundColor : "#576c89",
           height : 2,
           bottom : 0
       });
        
       var tableHeader = Ti.UI.createView({
           backgroundColor : "#bcbdc1",
           width : Ti.Platform.displayCaps.platformWidth,
           height : 60
       });
        
       tableHeader.add(border);
        
       var statusLabel = Ti.UI.createLabel({
           text : "Pull to Reload",
           left : 55,
           bottom : 30,
           height : "auto",
           color : "#FFF",
           textAlign : "center"
       });
        
       tableHeader.add(statusLabel);
       table.headerPullView = tableHeader;
        
       var pulling = false;
       var reloading = false;
       
       var overlay = Ti.UI.createView({
           opacity:.2,
           backgroundColor:'black'
       })
       
       function beginReloading() {
           searchBar.add(overlay);
           setTimeout(endReloading, 5000);
       }
        
       function endReloading() {
           searchBar.remove(overlay);
           table.setContentInsets({
               top : 0
           }, {
               animated : true
           });
           reloading = false;
           statusLabel.text = "Pull down to refresh...";
            
           table.separatorColor = 'transparent';
       }
        
       var offset = 0;
       table.addEventListener('scroll', function(e) {
           offset = e.contentOffset.y;
           if (offset <= -65.0 && !pulling) {
               pulling = true;
               statusLabel.text = "Release to refresh...";
           } else if (pulling && offset > -65.0 && offset < 0) {
               pulling = false;
               statusLabel.text = "Pull down to refresh...";
           }
       });
        
       table.addEventListener('dragEnd', function(e) {
           if (pulling && !reloading && offset <= -65.0) {
               reloading = true;
               pulling = false;
               statusLabel.text = "Reloading...";
               table.setContentInsets({
                   top : 60
               }, {
                   animated : true
               });
               beginReloading();
           }
       });
       
       function handleSearchBarFocus(_event){
           endReloading();
           setTimeout(function(){
               searchBar.focus();
           },300)
       }
        
       
       overlay.addEventListener("click", handleSearchBarFocus);
        
       tabGroup.addTab(tab1);
       tabGroup.open();
       
  6. Davide Cassenti 2013-09-05

    The solution proposed by [~vduggal] is not working if you reload more than once; steps: 1) pull down to refresh 2) click on the overlay (it works) 3) click to hide the search 4) repeat step 1: overlay is not added anymore I 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. These are the solutions tested:

    Solution 1

    Hide the bar using searchBar. The search bar is only hidden the first time.
       function beginReloading() {
           searchBar.hide(); // ONLY WORKS FIRST TIME
           reloadingTimeout = setTimeout(endReloading, 5000);
       }
       

    Solution 2

    I tried changing searchBar.hide() with table.search.hide() and it works:
       function beginReloading() {
           table.search.hide(); // WORKS FINE
           reloadingTimeout = setTimeout(endReloading, 5000);
       }
       

    Solution 3

    I tried to use table.search in combination with the add/remove overlay, but again no luck.
       function beginReloading() {
           table.search.add(overlay); // ONLY WORKS FIRST TIME
           reloadingTimeout = setTimeout(endReloading, 5000);
       }
       

    Notes

    I proposed solution 2 to the customer, waiting feedback.
  7. Sid Ghosh 2013-09-13

    Vishal Any update on this issue? Sid
  8. Vishal Duggal 2013-09-16

    [~sghosh],[~dcassenti] This 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) Currently 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.
       Titanium.UI.setBackgroundColor('#000');
         
       var tabGroup = Titanium.UI.createTabGroup();
         
       var win1 = Titanium.UI.createWindow({
           title : 'Table with Search',
           backgroundColor : '#fff'
       });
       var tab1 = Titanium.UI.createTab({
           icon : 'KS_nav_views.png',
           title : 'Table w/ Search',
           window : win1
       });
         
       var allNoteTypes = [{
           title : 'Plan 1'
       }, {
           title : 'Plan 2'
       }, {
           title : 'Plan 3'
       }];
         
       var refreshView = Ti.UI.createView({
           width : "100%",
           top : 0,
           height : 22,
           backgroundColor : "#000"
       });
         
       var lblRefreshTime = Ti.UI.createLabel({
           left : 5,
           width : '55%',
           text : "refreshed 1 min ago"
       });
         
       var searchBar = Ti.UI.createSearchBar({
           barColor : "#283D5A",
           autocorrect : false,
           autocapitalization : Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,
           hintText : "SR Number",
           keyboardType : Ti.UI.KEYBOARD_NUMBERS_PUNCTUATION
       });
         
       var table = Ti.UI.createTableView({
           top : 22,
           width : "100%",
           backgroundColor : 'transparent',
           hideSearchOnSelection : false,
           data : allNoteTypes,
           search : searchBar
       });
         
       refreshView.add(lblRefreshTime);
       win1.add(refreshView);
       win1.add(table);
         
       var border = Ti.UI.createView({
           backgroundColor : "#576c89",
           height : 2,
           bottom : 0
       });
         
       var tableHeader = Ti.UI.createView({
           backgroundColor : "#bcbdc1",
           width : Ti.Platform.displayCaps.platformWidth,
           height : 60
       });
         
       tableHeader.add(border);
         
       var statusLabel = Ti.UI.createLabel({
           text : "Pull to Reload",
           left : 55,
           bottom : 30,
           height : "auto",
           color : "#FFF",
           textAlign : "center"
       });
         
       tableHeader.add(statusLabel);
       table.headerPullView = tableHeader;
         
       var pulling = false;
       var reloading = false;
        
       var overlay = Ti.UI.createView({
           opacity:.2,
           backgroundColor:'black'
       })
        
       var timeOutCounter;
        
       function beginReloading() {
           searchBar.add(overlay);
           table.scrollable = false;
           timeOutCounter = setTimeout(function(){
               Ti.API.info('TIMEOUT');
               endReloading();
           },5000);
           Ti.API.info('setTimeout returned '+timeOutCounter);
       }
         
       function endReloading() {
           Ti.API.info('END Reloading called. Current Counter '+timeOutCounter);
           clearTimeout(timeOutCounter);
           searchBar.remove(overlay);
           table.scrollable = true;
           table.setContentInsets({
               top : 0
           }, {
               animated : true
           });
           reloading = false;
           statusLabel.text = "Pull down to refresh...";
       }
         
       var offset = 0;
       table.addEventListener('scroll', function(e) {
           if (reloading) {
               return;
           }
           offset = e.contentOffset.y;
           if (offset <= -65.0 && !pulling) {
               pulling = true;
               statusLabel.text = "Release to refresh...";
           } else if (pulling && offset > -65.0 && offset < 0) {
               pulling = false;
               statusLabel.text = "Pull down to refresh...";
           }
       });
         
       table.addEventListener('dragEnd', function(e) {
           if (reloading) {
               return;
           }
           if (pulling && !reloading && offset <= -65.0) {
               reloading = true;
               pulling = false;
               statusLabel.text = "Reloading...";
               table.setContentInsets({
                   top : 60
               }, {
                   animated : true
               });
               beginReloading();
           }
       });
        
       function handleSearchBarFocus(_event){
           Ti.API.info('FOCUS');
           endReloading();
           setTimeout(function(){
               searchBar.focus();
           },300)
       }
         
        
       overlay.addEventListener("click", handleSearchBarFocus);
         
       tabGroup.addTab(tab1);
       tabGroup.open();
       
  9. Vishal Duggal 2013-09-16

    Marking this as Won't Fix although this obviously shows a limitation of our current implementation of our built in search functionality. This should be resolved with the refresh Control ticket [TIMOB-12618] when we move to UITableViewController instead of a plain tableView.
  10. Lee Morris 2017-03-21

    Closing ticket as the issue will not fix.

JSON Source