infinite loop carousel

pull/874/head
ryanzhao 2 years ago
parent b4d414bbfe
commit c2f57700a5

@ -54,7 +54,7 @@ struct MessageInfoView: View {
}
// TODO: Attachment carousel view
SessionCarouselView_SwiftUI(colors: [.orange, .gray, .blue, .yellow])
SessionCarouselView_SwiftUI(contentInfos: [.orange, .gray, .blue, .yellow])
.frame(
maxWidth: .infinity,
maxHeight: .infinity,

@ -3,36 +3,44 @@
import SwiftUI
public struct SessionCarouselView_SwiftUI: View {
@State var index = 0
@State var index = 1
var colors: [Color]
var contentInfos: [Color]
let numberOfPages: Int
public init(colors: [Color]) {
self.colors = colors
public init(contentInfos: [Color]) {
self.contentInfos = contentInfos
self.numberOfPages = contentInfos.count
let first = self.contentInfos.first!
let last = self.contentInfos.last!
self.contentInfos.append(first)
self.contentInfos.insert(last, at: 0)
}
public var body: some View {
HStack(spacing: 0) {
ArrowView(value: $index.animation(.easeInOut), range: 0...(colors.count - 1), type: .decrement)
ArrowView(index: $index, numberOfPages: numberOfPages, type: .decrement)
.zIndex(1)
PageView(index: $index.animation(), maxIndex: colors.count - 1) {
ForEach(self.colors, id: \.self) { color in
PageView(index: $index, numberOfPages: self.numberOfPages) {
ForEach(self.contentInfos, id: \.self) { color in
Rectangle()
.foregroundColor(color)
}
}
.aspectRatio(1, contentMode: .fit)
ArrowView(value: $index.animation(.easeInOut), range: 0...(colors.count - 1), type: .increment)
ArrowView(index: $index, numberOfPages: numberOfPages, type: .increment)
.zIndex(1)
}
}
}
struct ArrowView: View {
@Binding var value: Int
let range: ClosedRange<Int>
@Binding var index: Int
let numberOfPages: Int
let maxIndex: Int
let type: ArrowType
enum ArrowType {
@ -40,9 +48,10 @@ struct ArrowView: View {
case decrement
}
init(value: Binding<Int>, range: ClosedRange<Int>, type: ArrowType) {
self._value = value
self.range = range
init(index: Binding<Int>, numberOfPages: Int, type: ArrowType) {
self._index = index
self.numberOfPages = numberOfPages
self.maxIndex = numberOfPages + 1
self.type = type
}
@ -63,36 +72,40 @@ struct ArrowView: View {
}
func decrement() {
if value > range.lowerBound {
value -= 1
withAnimation(.easeOut) {
self.index -= 1
}
if value < range.lowerBound {
value = range.lowerBound
if self.index == 0 {
self.index = self.maxIndex - 1
}
}
func increment() {
if value < range.upperBound {
value += 1
withAnimation(.easeOut) {
self.index += 1
}
if value > range.upperBound {
value = range.upperBound
if self.index == self.maxIndex {
self.index = 1
}
}
}
struct PageView<Content>: View where Content: View {
@Binding var index: Int
let numberOfPages: Int
let maxIndex: Int
let content: () -> Content
@State private var offset = CGFloat.zero
@State private var dragging = false
init(index: Binding<Int>, maxIndex: Int, @ViewBuilder content: @escaping () -> Content) {
init(index: Binding<Int>, numberOfPages: Int, @ViewBuilder content: @escaping () -> Content) {
self._index = index
self.maxIndex = maxIndex
self.numberOfPages = numberOfPages
self.content = content
self.maxIndex = numberOfPages + 1
}
var body: some View {
@ -120,12 +133,17 @@ struct PageView<Content>: View where Content: View {
withAnimation(.easeOut) {
self.dragging = false
}
switch self.index {
case 0: self.index = self.maxIndex - 1
case self.maxIndex: self.index = 1
default: break
}
}
)
}
.clipped()
PageControl(index: $index, maxIndex: maxIndex)
PageControl(index: $index, maxIndex: numberOfPages - 1)
.padding(EdgeInsets(top: 0, leading: 0, bottom: 8, trailing: 0))
}
}
@ -157,7 +175,7 @@ struct PageControl: View {
HStack(spacing: 4) {
ForEach(0...maxIndex, id: \.self) { index in
Circle()
.fill(index == self.index ? Color.white : Color.gray)
.fill(index == ((self.index - 1) % (self.maxIndex + 1)) ? Color.white : Color.gray)
.frame(width: 6.62, height: 6.62)
}
}
@ -180,7 +198,7 @@ struct SessionCarouselView_SwiftUI_Previews: PreviewProvider {
Color.black
}
SessionCarouselView_SwiftUI(colors: [.red, .orange, .blue])
SessionCarouselView_SwiftUI(contentInfos: [.red, .orange, .blue])
}
}
}

Loading…
Cancel
Save