0
votes

I'm currently using Appcelerator studio v4.5.0 and Ti SDK 5.2.2. This question concerns both iOS and Android since the behaviour appears to be the same.

I want to insert data at the top of a table. When I insert the data, I want the table to remain static aka Twitter. The data should appear above what the user is currently viewing with no jumping or moving of the table other than by the user. With all the methods I have tried what you were looking at gets pushed down by the number of rows added. If you add enough rows - the experience is jarring.

I have tried the following and all result in the table moving:

  • keeping the source array around, inserting to that and "refreshing" the entire data in the table (This old post - Disable autoscroll top on insertRowBefore in a TableView in Appcelerator/Titanium)
  • using table.insertRowBefore(index, row) and table.isertRowAfter(index, row)
  • adding the row(s) to a new section and using table.insertSectionBefore(index, section) and table.insertSectionAfter(index, section)
  • set table.scrollable to false (just to give it a go)

I am currently in the process of trying to use a mixture of knowing the row heights/number of rows and using table.scrollToIndex() or table.scrollToTop(). But so far both of these result in a very jumpy experience especially if the user is currently scrolling. On Android both of these functions take a finite position and half rows are not available.

Is there a setting that I am missing that forces the table to do this? Or is it pure indexing and what used to be index 5 in the table is now index 7 (after adding 2 rows) and the table stays at index 5? I would really hate to have to "design around this" since it is obviously possible.

Any help appreciated.

1
Is there a very much need to keep the table static as we should show users what data have been inserted/deleted? If it is very much needed (which also seems true from your very descriptive post), try look into this: TableViewAnimation Properties I will also try to do the same thing. Thanks - Prashant Saini
Thanks for your feedback. Yes it is important. The animation property is only for iOS. It also defaults to Titanium.UI.iPhone.TableViewScrollPosition.NONE - which I would think is what I want since the others try to place the inserted row on the visible screen. - Brad White
Yes, I forgot to mention that this property is only on iOS. On Android, you could try these steps: 1. Set table opacity to 0.... 2. Then calculate the position where you were at previously.... 3. Insert row now.... 4. Scroll to the previously calculated position... 5. Reset the tableview opacity to 1... I think it will at least remove the chances of jumpy scrolling and it will merely take milliseconds to run this process, so it should work where no other solution seems feasible. Also note that do not set visible property, use only opacity, as visible property might alter the tableview. - Prashant Saini
This might make a great feature request. Stack Overflow is not the right place for that. Please check if it has already been requested at the Appcelerator JIRA. If it has not, create a ticket, link to this question but also provide a complete description in the ticket. Don't forget to drop a link to the ticket here so that others can watch it with you. - Fokke Zandbergen

1 Answers

0
votes

Well, it seems that there is no setting that stops the table from scrolling on insert since it is really only to trying to keep the user at the index it last was at. However, the following works fairly seemlessly on iOS. To alleviate jumping on Android go with @PrashantSaini approach.

On scroll event for the table, store the position of the user:

var scrollPos;
self.addEventListener('scroll',function(e){
    if(Ti.Platform.osname === 'android'){
        scrollPos = e.firstVisibleItem;
    }else{
        scrollPos = e.contentOffset.y;
    }
}

Then, just after you insert the row/section, use scrollToTop to set the viewing poistion of the table.

table.insertRowBefore(indexToInsert,tableData[i],{animated:false});

//Adjust the scroll position for the height of the row for iOS and index for Android
scrollPos += (Ti.Platform.osname === 'android')?1:200;

//Make table opaque for a while while it does its thing - Android only
if(Ti.Platform.osname === 'android'){table.opacity = 0.2;}

//Do the scroll
table.scrollToTop(scrollPos, {animated:false});

//Opacity back to normal in Android
if(Ti.Platform.osname === 'android'){table.opacity = 1.0;}

Note that this will result in a jump for Android and also requires you to know the height of the row you are inserting.