I want to show a view, where the user can add or remove items shown as icons, which are sorted in two groups: squares and circles.
When there are only squares, they should be shown in one row:
[] [] []
When there are so many squares that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all squares are visible.
When there are only circles, they also should be shown in one row:
() () ()
When there are so many circles that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all circles are visible.
When there a few squares and a few circles, they should be shown adjacent in one row:
[] [] () ()
When there are so many squares and circles that they don’t fit horizontally, they should be shown in two rows, squares on top, circles below:
[] [] []
() () ()
When there are either too many squares or too many circles (or both) to fit horizontally, one common (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all items are visible.
I started with ViewThatFits: (see first code block)
{ let squares = HStack { ForEach(model.squares, id: \.self) { square in Image(square) } } let circles = HStack { ForEach(model.circles, id: \.self) { circle in Image(circle) } } let oneLine = HStack { squares circles } let twoLines = VStack { squares circles } let scrollView = ScrollView(.horizontal) { twoLines }.scrollIndicators(.visible) ViewThatFits(in: .horizontal) { oneLine twoLines scrollView.clipped() } }
While this works in general, it doesn’t animate properly.
When the user adds or removes an image the model gets updated, (see second code block)
withAnimation(Animation.easeIn(duration: 0.25)) { model.squares += image }
and the view animates with the existing images either making space for a new appearing square/circle, or moving together to close the gap where an image disappeared. This works fine as long as ViewThatFits returns the same view.
However, when adding 1 image leads to ViewThatFits switching from oneLine to twoLines, this switch is not animated. The circles jump to the new position under the squares, instead of sliding there.
I searched online for a solution, but this seems to be a known problem of ViewThatFits. It doesn't animate when it switches...
(tbc)