|
@@ -31,13 +31,13 @@ class ACarouselViewModel<Data, ID>: ObservableObject where Data : RandomAccessCo
|
|
|
private let _data: Data
|
|
private let _data: Data
|
|
|
private let _dataId: KeyPath<Data.Element, ID>
|
|
private let _dataId: KeyPath<Data.Element, ID>
|
|
|
private let _spacing: CGFloat
|
|
private let _spacing: CGFloat
|
|
|
- private let _headspace: CGFloat
|
|
|
|
|
|
|
+ private let _contentPadding: [Int]
|
|
|
private let _isWrap: Bool
|
|
private let _isWrap: Bool
|
|
|
private let _sidesScaling: CGFloat
|
|
private let _sidesScaling: CGFloat
|
|
|
private let _autoScroll: ACarouselAutoScroll
|
|
private let _autoScroll: ACarouselAutoScroll
|
|
|
private let _canMove: Bool
|
|
private let _canMove: Bool
|
|
|
|
|
|
|
|
- init(_ data: Data, id: KeyPath<Data.Element, ID>, index: Binding<Int>, spacing: CGFloat, headspace: CGFloat, sidesScaling: CGFloat, isWrap: Bool, autoScroll: ACarouselAutoScroll, canMove: Bool) {
|
|
|
|
|
|
|
+ init(_ data: Data, id: KeyPath<Data.Element, ID>, index: Binding<Int>, spacing: CGFloat, contentPadding: [Int], sidesScaling: CGFloat, isWrap: Bool, autoScroll: ACarouselAutoScroll, canMove: Bool) {
|
|
|
|
|
|
|
|
guard index.wrappedValue < data.count else {
|
|
guard index.wrappedValue < data.count else {
|
|
|
fatalError("The index should be less than the count of data ")
|
|
fatalError("The index should be less than the count of data ")
|
|
@@ -46,7 +46,7 @@ class ACarouselViewModel<Data, ID>: ObservableObject where Data : RandomAccessCo
|
|
|
self._data = data
|
|
self._data = data
|
|
|
self._dataId = id
|
|
self._dataId = id
|
|
|
self._spacing = spacing
|
|
self._spacing = spacing
|
|
|
- self._headspace = headspace
|
|
|
|
|
|
|
+ self._contentPadding = contentPadding
|
|
|
self._isWrap = isWrap
|
|
self._isWrap = isWrap
|
|
|
self._sidesScaling = sidesScaling
|
|
self._sidesScaling = sidesScaling
|
|
|
self._autoScroll = autoScroll
|
|
self._autoScroll = autoScroll
|
|
@@ -105,8 +105,8 @@ class ACarouselViewModel<Data, ID>: ObservableObject where Data : RandomAccessCo
|
|
|
|
|
|
|
|
extension ACarouselViewModel where ID == Data.Element.ID, Data.Element : Identifiable {
|
|
extension ACarouselViewModel where ID == Data.Element.ID, Data.Element : Identifiable {
|
|
|
|
|
|
|
|
- convenience init(_ data: Data, index: Binding<Int>, spacing: CGFloat, headspace: CGFloat, sidesScaling: CGFloat, isWrap: Bool, autoScroll: ACarouselAutoScroll, canMove: Bool) {
|
|
|
|
|
- self.init(data, id: \.id, index: index, spacing: spacing, headspace: headspace, sidesScaling: sidesScaling, isWrap: isWrap, autoScroll: autoScroll, canMove: canMove)
|
|
|
|
|
|
|
+ convenience init(_ data: Data, index: Binding<Int>, spacing: CGFloat, contentPadding: [Int], sidesScaling: CGFloat, isWrap: Bool, autoScroll: ACarouselAutoScroll, canMove: Bool) {
|
|
|
|
|
+ self.init(data, id: \.id, index: index, spacing: spacing, contentPadding: contentPadding, sidesScaling: sidesScaling, isWrap: isWrap, autoScroll: autoScroll, canMove: canMove)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -142,7 +142,7 @@ extension ACarouselViewModel {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var itemWidth: CGFloat {
|
|
var itemWidth: CGFloat {
|
|
|
- max(0, viewSize.width - defaultPadding * 2)
|
|
|
|
|
|
|
+ max(0, viewSize.width - defaultLeftPadding - defaultRightPadding)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var timer: TimePublisher? {
|
|
var timer: TimePublisher? {
|
|
@@ -177,8 +177,12 @@ extension ACarouselViewModel {
|
|
|
return t > 0 ? _autoScroll : .defaultActive
|
|
return t > 0 ? _autoScroll : .defaultActive
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private var defaultPadding: CGFloat {
|
|
|
|
|
- return (_headspace + spacing)
|
|
|
|
|
|
|
+ private var defaultLeftPadding: CGFloat {
|
|
|
|
|
+ return CGFloat(_contentPadding[0]) + spacing
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private var defaultRightPadding: CGFloat {
|
|
|
|
|
+ return CGFloat(_contentPadding[1]) + spacing
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private var itemActualWidth: CGFloat {
|
|
private var itemActualWidth: CGFloat {
|
|
@@ -201,7 +205,7 @@ extension ACarouselViewModel {
|
|
|
/// current offset value
|
|
/// current offset value
|
|
|
var offset: CGFloat {
|
|
var offset: CGFloat {
|
|
|
let activeOffset = CGFloat(activeIndex) * itemActualWidth
|
|
let activeOffset = CGFloat(activeIndex) * itemActualWidth
|
|
|
- return defaultPadding - activeOffset + dragOffset
|
|
|
|
|
|
|
+ return defaultLeftPadding - activeOffset + dragOffset
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// change offset when acitveItem changes
|
|
/// change offset when acitveItem changes
|
|
@@ -211,8 +215,8 @@ extension ACarouselViewModel {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let minimumOffset = defaultPadding
|
|
|
|
|
- let maxinumOffset = defaultPadding - CGFloat(data.count - 1) * itemActualWidth
|
|
|
|
|
|
|
+ let minimumOffset = defaultLeftPadding
|
|
|
|
|
+ let maxinumOffset = defaultLeftPadding - CGFloat(data.count - 1) * itemActualWidth
|
|
|
|
|
|
|
|
if offset == minimumOffset {
|
|
if offset == minimumOffset {
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|