Has anyone implemented pull-down-to-refresh for widget.newTableView() ?

I noticed a while back that someone had asked for this in the api for newTableView(), but as far as I can tell there is no Corona function for it as yet.

Has anyone managed to come up with a reliable working version? Obviously I’m aware that updating the content to be displayed will be up to us, I’m simply curious about the mechanics of the pull down implementation.

I have tried making row 1 the “pull down to refresh” row, and the as soon as the list appears using:

list:scrollToIndex( 2, 0 )

to “push” it up above the top of the screen. The problem here is that if I touch the list at all and then release the list autoscrolls back to index 1 (unless there are enough rows to fill the screen but that’s not the case when the user first uses the app since they are rows of user data).

I also tried using a frame listener to check the position of the list itself - if it had been pulled down enough then it would trigger a reload:

if list:getContentPosition() \>=0 then...

The problem with this is that I don’t want it to refresh unless the user RELEASES their touch with the list scrolled down - if they pull it down then change their mind, they should be able to scroll back themselves and prevent the refresh from starting. To make this happen would require the list (NOT the rows but the list itself) to have a touch listener checking for a release, but to have touch listeners for the list on top of touch listeners for the rows (and touch listeners on buttons within the row) seems very messy.

So…does anyone have any suggestions, as I imagine it’s something that is fairly useful for anyone who uses tableViews? [import]uid: 84115 topic_id: 32496 reply_id: 332496[/import]

Yes I have. It’s not perfect. Basically newTableView generates events when the list scrolls and you can pass a listener callback function as a parameter when you create the tableview. You get events:

beganScroll
endedScroll and
movingToTopLimit

When I detect the beganScroll I ad a Runtime listener for enterFrame that has my function to draw the two display objects to show (the pull down and the, “I’ve pulled it down enough now you can release to refresh” art.) I use list:getContentPosition() to record my starting position.

I’m not actually using endedScroll.

Finally during the movingToTopLimit phase, I remove the runtime listener, hide my graphics and if my reload flag is true, trigger the code to redraw the list.

Then in my runtime listener is where all the magic happens. I reposition the two graphics so that they use the current list position (y = list:getContentPosition()) to determine where the others need to go. The down graphic is set to alpha 1, the up graphic set to alpha 0. Once I see that I’m past my threshhold (I’m using 55 pixels based in the size of my art), i set a flag that I need to reload to true, hide the down graphic, show the upgraphic

It seems complicated at first, and there is math involved because your list position and graphics are center based so you have to compute the 'y" based on all of that. And Runtime listeners can scare people. Now I had to do funky things too like the graphic for showing the pull down and release to reload graphics tops have to be masked or hidden some how so they appear to slide out from under something, but thats just a matter of overlaying a snippet of your background on top.
[import]uid: 19626 topic_id: 32496 reply_id: 129251[/import]

Thanks for the reply, would you mind explaining exactly how I access those scroll events please?

I have tried the following:

local function testFunction(event)  
 print("Event name = "..event.name)  
 print("Event phase = "..event.phase)  
end  
  
local listOptions = {  
 top = 0,  
 height = getScreenHeight(),  
 left = 0,   
 width = getScreenWidth(),  
 bgColor = {255, 0, 0, 255},  
 listener = testFunction, --also tried onEvent= and onScroll=  
 }  
  
 list = widget.newTableView( listOptions )  
  

The “event.name” prints out “enterFrame” when I first scroll, and prints “scrollEvent” and “enterFrame” when I release. I presume these are corresponding to the 3 events you mentioned, but how did you get those 3 specific events? I have tried using “onEvent” or “onScroll” in place of “listener” but never get those events. In all cases, event.phase returns nil.
[import]uid: 84115 topic_id: 32496 reply_id: 129261[/import]

Scratch that, I’ve just worked out that it’s event.type to get those values.
Thanks again. [import]uid: 84115 topic_id: 32496 reply_id: 129264[/import]

Sorry @alan120184, I didn’t notice you were a test driver. It was fixed around daily build 929 or later. You will have to be a subscriber to pickup that fix and quite a few other storyboard and widget fixes in 929 and later. You also will need a later build to build for iOS 6 and the iPhone 5 as well.

[import]uid: 19626 topic_id: 32496 reply_id: 129276[/import]

My boss is a subscriber so I was still able to test it out on his machine.
All of the reloading/redrawing stuff I can manage, it was just trying to access the “ended touch” that I needed. I’m surprised that I couldn’t find a blog entry that covered this. If I ever have time I’ll try and write up a nice clear description or class for people to use - unless you already planned on doing it :slight_smile: [import]uid: 84115 topic_id: 32496 reply_id: 129278[/import]

Yes I have. It’s not perfect. Basically newTableView generates events when the list scrolls and you can pass a listener callback function as a parameter when you create the tableview. You get events:

beganScroll
endedScroll and
movingToTopLimit

When I detect the beganScroll I ad a Runtime listener for enterFrame that has my function to draw the two display objects to show (the pull down and the, “I’ve pulled it down enough now you can release to refresh” art.) I use list:getContentPosition() to record my starting position.

I’m not actually using endedScroll.

Finally during the movingToTopLimit phase, I remove the runtime listener, hide my graphics and if my reload flag is true, trigger the code to redraw the list.

Then in my runtime listener is where all the magic happens. I reposition the two graphics so that they use the current list position (y = list:getContentPosition()) to determine where the others need to go. The down graphic is set to alpha 1, the up graphic set to alpha 0. Once I see that I’m past my threshhold (I’m using 55 pixels based in the size of my art), i set a flag that I need to reload to true, hide the down graphic, show the upgraphic

It seems complicated at first, and there is math involved because your list position and graphics are center based so you have to compute the 'y" based on all of that. And Runtime listeners can scare people. Now I had to do funky things too like the graphic for showing the pull down and release to reload graphics tops have to be masked or hidden some how so they appear to slide out from under something, but thats just a matter of overlaying a snippet of your background on top.
[import]uid: 19626 topic_id: 32496 reply_id: 129251[/import]

Thanks for the reply, would you mind explaining exactly how I access those scroll events please?

I have tried the following:

local function testFunction(event)  
 print("Event name = "..event.name)  
 print("Event phase = "..event.phase)  
end  
  
local listOptions = {  
 top = 0,  
 height = getScreenHeight(),  
 left = 0,   
 width = getScreenWidth(),  
 bgColor = {255, 0, 0, 255},  
 listener = testFunction, --also tried onEvent= and onScroll=  
 }  
  
 list = widget.newTableView( listOptions )  
  

The “event.name” prints out “enterFrame” when I first scroll, and prints “scrollEvent” and “enterFrame” when I release. I presume these are corresponding to the 3 events you mentioned, but how did you get those 3 specific events? I have tried using “onEvent” or “onScroll” in place of “listener” but never get those events. In all cases, event.phase returns nil.
[import]uid: 84115 topic_id: 32496 reply_id: 129261[/import]

Scratch that, I’ve just worked out that it’s event.type to get those values.
Thanks again. [import]uid: 84115 topic_id: 32496 reply_id: 129264[/import]

Sorry @alan120184, I didn’t notice you were a test driver. It was fixed around daily build 929 or later. You will have to be a subscriber to pickup that fix and quite a few other storyboard and widget fixes in 929 and later. You also will need a later build to build for iOS 6 and the iPhone 5 as well.

[import]uid: 19626 topic_id: 32496 reply_id: 129276[/import]

My boss is a subscriber so I was still able to test it out on his machine.
All of the reloading/redrawing stuff I can manage, it was just trying to access the “ended touch” that I needed. I’m surprised that I couldn’t find a blog entry that covered this. If I ever have time I’ll try and write up a nice clear description or class for people to use - unless you already planned on doing it :slight_smile: [import]uid: 84115 topic_id: 32496 reply_id: 129278[/import]

Hi AlanPlantPot,

Did get anywhere with your experiments?

[import]uid: 189638 topic_id: 32496 reply_id: 134833[/import]

Hi AlanPlantPot,

Did get anywhere with your experiments?

[import]uid: 189638 topic_id: 32496 reply_id: 134833[/import]