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.
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
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.
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:
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).