Get and restore scroll position of an iOSMobileTable

Hi,

I’d like to achieve the following:
• Store the scroll position of an iOSMobileTable
• Remove all rows from the table
• Fill the table again (with changes, of course)
• Restore the scroll position like it was before

(currently, the table always jumps to top when re-filling the list, and that’s not great).

So, I found one way to set the scroll position, using the built-in iOSMobileTable.ScrollToRow method and one way to get the scroll position, using the GetScrollPositionXC method of the iOSDesignExtensions project, but they don’t seem compatible.

The current code is like this:

Var ScrollPosition() As Integer=TBLMain.GetScrollPositionXC

TBLMain.RemoveAllRows
TBLMain.AddSection "List"+if(Items.Count=0," (empty)","")

//Add the items
for each AnItem as CItem in Items
  AddItemToList AnItem
next

if ScrollPosition(0)>-1 and ScrollPosition(1)>-1 then TBLMain.ScrollToRow(ScrollPosition(0),ScrollPosition(1))
SetEditMode 0

The values of ScrollPosition looks like expected (e.g. (0,1)) but the table doesn’t scroll.

My first question would be “How to make it working?”.

I have yet another problem, because both the Get and Set methods use rounded positions. So when the table is scrolled in a way where the first row is truncated, this code (even if it worked) would round the scroll position. I don’t find these methods efficient because of this.

TIA for help.

Not my area of expertise, but could you use the existing rows and replace their data without removing them first? Then you either add or delete rows from the bottom of the list depending on how the numbers of rows differ. That might prove more seamless to the user.

As you are already using iOSDesignExtensions, try adding these two functions to a new module:

Public Function GetContentOffsetXC(extends table As iOSMobileTable) As Point
  
  Dim offset As point
  
  Declare Function ContentOffset_ Lib "UIKit.framework" selector "contentOffset" (obj_id As ptr) As ExtensionsXC.xcCGPoint
  Dim pt As ExtensionsXC.xcCGPoint = ContentOffset_(table.Handle)
  offset = New Point(pt.x, pt.y)
  
  Return offset
End Function
Public Sub SetContentOffsetXC(extends table As iOSMobileTable, point As Point, animated As Boolean = True)
  
  Declare Sub setContentOffsetAnimated Lib "UIKit.framework" selector "setContentOffset:animated:" (id As ptr, value As ExtensionsXC.xcCGPoint, animated As Boolean)
  
  Dim pt As ExtensionsXC.xcCGPoint
  pt.x = point.X
  pt.y = point.Y
  
  setContentOffsetAnimated(table.Handle, pt, animated)
End Sub

Then use like this:

//tableOffset is a property of the MobileScreen
tableOffset = table.GetContentOffsetXC

//Reload rows
...

//Defer updating the scroll position because adding/removing rows can be async
Timer.CallLater(200, AddressOf ScrollTable)
Sub ScrollTable
  table.SetContentOffset(tableOffset)
End Sub
2 Likes

I agree it would work, but it’s precisely when my data gets out of sync that I need to refresh all. The data can be used at more than one place at once; refreshing by removing al is the easiest solution I found (it’s an in-house app, so I don’t plan to add complex functions to sync).
Thanks for the idea, anyway.

Thanks, I’ll try.
I’m currently facing the problem that it looks like Xojo’s ScrollToRow doesn’t work on my side (I tried with explicit values like “TBLMain.ScrollToRow(0,2)” to be sure and the table remains at the top); since I haven’t see any report about this issue, and it would be obviously reported if it was Xojo’s fault, I’m guessing I’m not using it correctly, but it’s hard to find why, especially since it’s a simple method. :man_shrugging:

The code you are using will scroll to the second row in the first section. If the row is already visible, the table will not scroll.
Unless you specifically tell it to scroll the row at the top:

TBLMain.ScrollToRow(0, 2, True, iOSMobileTable.ScrollPositions.Top)
2 Likes

Thanks; that’s the bit I wasn’t aware of. I guess it would be useful in the documentation.
(my point of view was that the ScrollPositions enumeration was just for the visual effect and wouldn’t interfere with the behaviour).