Post APkat24I6XTvt1mkK0 by shadowfacts@social.shadowfacts.net
 (DIR) More posts by shadowfacts@social.shadowfacts.net
 (DIR) Post #APkat24I6XTvt1mkK0 by shadowfacts@social.shadowfacts.net
       2022-11-19T04:35:19.362353Z
       
       0 likes, 0 repeats
       
       in fairness to swiftui, sometimes using uikit feels like constantly running into brick walls tooi want to insert some cells into a collection view and have the position of bottom cells not change on screen. so i do some fiddling with the contentOffset and it works. and then i try to do the exact same thing elsewhere, in marginally different circumstances (scrolled down farther) and it doesn't. after inserting the items, i set the contentOffset to the new one i calculated to maintain the screen-position of the bottom cells from before the insertion, and then it jumps around even more. wtf
       
 (DIR) Post #APkc2LJ2339c6zgRaS by shadowfacts@social.shadowfacts.net
       2022-11-19T04:48:12.460019Z
       
       0 likes, 0 repeats
       
       if i just keep on trying to set the contentOffset, runloop iteration after runloop iteration, it seems to work, like it somehow converges on the right value. but the number of iterations it takes seems to depend on the location of the bottom of the newly inserted cellslike, if the bottom of the new cell is towards the top of the screen, only one or two sets is fine. but if the bottom of the bottom-most new cell is in the middle of screen, it takes three iterations
       
 (DIR) Post #APkc9scgZhMHTBTEYa by shadowfacts@social.shadowfacts.net
       2022-11-19T04:49:34.587898Z
       
       0 likes, 0 repeats
       
       i love a nice dispatchqueue.main.async hack as much as the next guy, but this absurdwhen doing this in the other circumstances, i can set the content offset in the dataSource.apply completion handler and it's perfectly fine—no further jumping around
       
 (DIR) Post #APkcaUROaijEHysW2K by jjoelson@mastodon.social
       2022-11-19T04:47:36Z
       
       0 likes, 0 repeats
       
       @shadowfacts Are you using self-sizing cells? I find that can cause the offsets to be automatically recalculated at unexpected times.
       
 (DIR) Post #APkcaUxeemX5u1yHJo by shadowfacts@social.shadowfacts.net
       2022-11-19T04:54:22.182607Z
       
       0 likes, 0 repeats
       
       @jjoelson yeah, I am, and that does not surprise meI think what's happening is when I first set the correct content offset, a bunch of the newly-inserted cells still have whatever placeholder height and then setting the content offset caused them to be sized properly—altering the offset
       
 (DIR) Post #APkchFFVTLBHCRXRB2 by shadowfacts@social.shadowfacts.net
       2022-11-19T04:55:36.539140Z
       
       0 likes, 0 repeats
       
       and yes, all those are load-bearingsetting contentOffset seems to make the collection view recalculate the content size, thus changing the actual offset that's necessary to preserve the  apparent scroll position
       
 (DIR) Post #APkd8dvNpzbHY2BrBw by libei@mastodon.social
       2022-11-19T04:58:24Z
       
       0 likes, 0 repeats
       
       @shadowfacts does you collection view use any estimate stuff?
       
 (DIR) Post #APkd8eRdu3P9A5HcTQ by shadowfacts@social.shadowfacts.net
       2022-11-19T05:00:32.712122Z
       
       0 likes, 0 repeats
       
       @libei not that I'm setting (does that even exist for compositional layouts?), but presumably it's estimating it internally
       
 (DIR) Post #APkdlqNPTVslSdzYFE by jjoelson@mastodon.social
       2022-11-19T05:01:01Z
       
       0 likes, 0 repeats
       
       @shadowfacts I posted this yesterday about coming to the realization that we probably still need to calculate cell heights manually for certain types of feed-centric apps: https://mastodon.social/@jjoelson/109360437410712685
       
 (DIR) Post #APkdlqq7kkqothQU08 by shadowfacts@social.shadowfacts.net
       2022-11-19T05:07:38.371886Z
       
       0 likes, 0 repeats
       
       @jjoelson yeah, that's possible. but I really don't want to have to because 90% of my app is scrolling lists of self-sizing things :/
       
 (DIR) Post #APkdzLxrLLMxC4TylM by libei@mastodon.social
       2022-11-19T05:05:24Z
       
       0 likes, 0 repeats
       
       @shadowfacts if your cells are self sizing then your collection view should being using estimation stuff.
       
 (DIR) Post #APkdzMRzXJTKhWa2jI by shadowfacts@social.shadowfacts.net
       2022-11-19T05:10:04.308822Z
       
       0 likes, 0 repeats
       
       @libei they may be, but not that I directly control. estimatedItemSize only exists on UICollectionViewFlowLayout, and I'm using a list-style compositional layout.
       
 (DIR) Post #APleHRuaAHkQ0cXReC by json@micro.sadlerjw.com
       2022-11-19T05:37:35Z
       
       0 likes, 0 repeats
       
       @libei @shadowfacts I’m guessing this is an estimated —> measured size thing too, under the hood, although I have no idea how you’d fix it. If you’re on Twitter, Tyler Fox (@smileyborg) is an amazing resource for table/collection view questions. (Don’t know if he’s on mastodon anywhere.)
       
 (DIR) Post #APleHSNIRWiTRfyNP6 by libei@mastodon.social
       2022-11-19T16:20:19Z
       
       1 likes, 0 repeats
       
       @json @shadowfacts I think list-style compositional layout should be using estimated hight, you can check this API of compositional layout: https://developer.apple.com/documentation/uikit/nscollectionlayoutdimension/3199057-estimatedFor table views and collection views that use estimation API (self-sizing cells), set contentOffset will lead to unstable result. The more stable way I'm using is save the top item indexPath and visible offset then use scrollToItem/scrollToRow
       
 (DIR) Post #APleHVDTsTeCG6P51M by libei@mastodon.social
       2022-11-19T16:21:57Z
       
       0 likes, 0 repeats
       
       @json @shadowfacts But this still have issues when the cell's height is too long. :welp:
       
 (DIR) Post #APleUxh5JIsMLQfUx6 by shadowfacts@social.shadowfacts.net
       2022-11-19T16:50:30.387747Z
       
       0 likes, 0 repeats
       
       @libei @json offset in your example is the offset within that particular cell? that seems like it should work fine, even if the cell is really tall
       
 (DIR) Post #APlhxbZQwY8VzTRIdk by libei@mastodon.social
       2022-11-19T17:11:59Z
       
       1 likes, 0 repeats
       
       @shadowfacts @json Yes, the offset is the cell’s top to visible rect before applying changes.It seems work fine on tall cells, but in practice sometimes I see weird behavior with tall cells.
       
 (DIR) Post #APoQ7294IDwtJfKifI by shadowfacts@social.shadowfacts.net
       2022-11-21T00:53:26.556498Z
       
       0 likes, 0 repeats
       
       dammit. turns out my 3-async hack did not work on a real device
       
 (DIR) Post #APoZTr9uCoizURgN3A by brunoph@breakpoint.cafe
       2022-11-21T01:08:08Z
       
       1 likes, 0 repeats
       
       @shadowfacts :saddestcat:
       
 (DIR) Post #APqSTjP8gpdD09YBRA by shadowfacts@social.shadowfacts.net
       2022-11-22T00:29:22.808887Z
       
       0 likes, 0 repeats
       
       ayy, got a different way of maintaining the bottom-relative scroll position working! it is significantly less stupid and works on real devices
       
 (DIR) Post #APqTfeODGF1qsRMem0 by shadowfacts@social.shadowfacts.net
       2022-11-22T00:42:43.813474Z
       
       0 likes, 0 repeats
       
       the trick is that scrollToItem(at:at:animated:) works correctly for scrolling to unmeasured cellsbut: I can't just scroll to the that was below the gap before and then scroll down a little bit more to match the offset, because that scrolling down would be moving the viewport into unmeasured cells—and that's what fucks everything upso, instead, I scroll to the item _above_ the one whose screen-position i need to maintain and force it to be measured. then, I can scroll to the actual cell I care about and scroll back up a little bit without touching any unmeasured cells(the slight wrinkle is that the cell immediately above the one of interest may not provide enough height to fill the gap between the top of the screen and the top of the cell I care about, so the previous step continues in a loop until there's enough measured height accumulated)
       
 (DIR) Post #ARyLSr7Vzi9LAAK8xM by kyle@mister.computer
       2023-01-24T07:50:12Z
       
       1 likes, 0 repeats
       
       @shadowfacts The only way I have solved this in a robust way (that also supports automatic animations) is a custom collection view layout. That’s the only way to “get in the middle” of the layout process to adjust the content offset at the same time as new elements are added. At a high level, I calculate the size of all the items in each update pass and figure out where they are in relation to the viewport. Then adjust the content offset to maintain the old viewport.
       
 (DIR) Post #ARyLSrfByV5Wqc52Rs by kyle@mister.computer
       2023-01-24T08:08:44Z
       
       1 likes, 0 repeats
       
       @shadowfacts (I’m sure you’re not looking for advice on a three-month old post but I enjoyed reading your post history and blog after discovering you. Couldn’t help myself.)
       
 (DIR) Post #ARyLoWWnEjMBfTTnJQ by shadowfacts@social.shadowfacts.net
       2023-01-24T15:36:33.234662Z
       
       0 likes, 0 repeats
       
       @kyle for that issue specifically, I did end up with a solution that's not too terribly hacky, but these days I am increasingly leaning in the direction of something more custom.my solution largely works, but still has issues with the viewport jumping around if the user is actively scrolling while there's an update (except that's not reliably reproducible, so there's probably some even more complex edge case).and my most recent hangup is that I can't make the compositional layout's readable content inset behave the way I want, and a custom layout seems like the best way of reimplementing that myself
       
 (DIR) Post #ARzCt0KbfImSpYnj0K by kyle@mister.computer
       2023-01-24T21:11:32Z
       
       1 likes, 0 repeats
       
       @shadowfacts Subclassing does explicitly let you control the content offset while scrolling. I do wish that the compositional layout subclass was also meant to be subclassed so we could still tweak those few things that we can't compose ☹️