Skip to content

Commit d922f30

Browse files
authored
fix: 🐛 Carousel Empty Space Shown After Removing Last (jira:752 (#1099)
Cherrypick
1 parent 3242342 commit d922f30

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

Sources/FioriSwiftUICore/Views/Carousel.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ public struct Carousel<Content>: View where Content: View {
262262
.onPreferenceChange(CarouselContentSizePreferenceKey.self) { size in
263263
DispatchQueue.main.async {
264264
self.contentSize = size
265+
let finalX = self.calculateContentOffsetX(from: self.contentOffset.x)
266+
if abs(finalX.distance(to: self.contentOffset.x)) > 0.1 {
267+
self.contentOffset.x = finalX
268+
self.preContentOffset = self.contentOffset
269+
}
265270
}
266271
}
267272
.contentShape(Rectangle())
@@ -272,17 +277,8 @@ public struct Carousel<Content>: View where Content: View {
272277
}
273278
.onEnded { value in
274279
withAnimation(.easeOut(duration: 0.5)) {
275-
let maxX = max(0, contentSize.width - self.viewSize.width)
276280
let expectedX = max(0, preContentOffset.x + (self.layoutDirection == .leftToRight ? -1 : 1) * value.predictedEndTranslation.width)
277-
var finalX = min(maxX, expectedX)
278-
279-
if self.isSnapping {
280-
let itemWidth: CGFloat = (viewSize.width - self.contentInsets.horizontal - CGFloat(self.numberOfColumns + 2) * self.spacing) / CGFloat(self.numberOfColumns)
281-
let index = ((expectedX - self.contentInsets.leading) / (itemWidth + self.spacing)).rounded()
282-
let idealX = index * itemWidth + max(0, index - 1) * self.spacing + (index == 0 ? 0 : self.contentInsets.leading)
283-
finalX = max(0, min(maxX, idealX))
284-
}
285-
281+
let finalX = self.calculateContentOffsetX(from: expectedX)
286282
self.contentOffset.x = finalX
287283
self.preContentOffset = self.contentOffset
288284
}
@@ -293,9 +289,28 @@ public struct Carousel<Content>: View where Content: View {
293289
.onPreferenceChange(CarouselSizePreferenceKey.self) { size in
294290
DispatchQueue.main.async {
295291
self.viewSize = size
292+
let finalX = self.calculateContentOffsetX(from: self.contentOffset.x)
293+
if abs(finalX.distance(to: self.contentOffset.x)) > 0.1 {
294+
self.contentOffset.x = finalX
295+
self.preContentOffset = self.contentOffset
296+
}
296297
}
297298
}
298299
}
300+
301+
func calculateContentOffsetX(from x: CGFloat) -> CGFloat {
302+
let maxX = max(0, contentSize.width - self.viewSize.width)
303+
var finalX = min(maxX, x)
304+
305+
if self.isSnapping {
306+
let itemWidth: CGFloat = (viewSize.width - self.contentInsets.horizontal - CGFloat(self.numberOfColumns + 2) * self.spacing) / CGFloat(self.numberOfColumns)
307+
let index = ((x - self.contentInsets.leading) / (itemWidth + self.spacing)).rounded()
308+
let idealX = index * itemWidth + max(0, index - 1) * self.spacing + (index == 0 ? 0 : self.contentInsets.leading)
309+
finalX = max(0, min(maxX, idealX))
310+
}
311+
312+
return finalX
313+
}
299314
}
300315

301316
#Preview {

0 commit comments

Comments
 (0)