Skip to content

Instantly share code, notes, and snippets.

@diogoos
Created April 1, 2021 09:59
Show Gist options
  • Select an option

  • Save diogoos/eb37848c0ebf6289e5d47e003ba2342c to your computer and use it in GitHub Desktop.

Select an option

Save diogoos/eb37848c0ebf6289e5d47e003ba2342c to your computer and use it in GitHub Desktop.
A mini image carousel to display thumbnails
struct ThumbnailSlideView: View {
// parameters
@Binding var images: [UIImage]
// element sizing
var size: CGFloat = 100
var spacing: CGFloat = 16
private var pageSize: CGFloat { size + spacing }
private var marginAdjust: CGFloat { pageSize / 2 }
// internal position trackers
@State private var offset: CGFloat = 0
@State private var lastCount: Int = 0
@State private var currentPage: Int = -1
var body: some View {
VStack {
HStack(spacing: spacing) {
ForEach(images, id: \.hashValue) { image in
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: size, height: size)
.cornerRadius(5)
}
}
.offset(x: offset, y: 0)
.onReceive(images.publisher.receive(on: RunLoop.main), perform: { _ in
if lastCount < images.count {
if images.count > 1 { offset -= marginAdjust } // no need to offset the first image
currentPage += 1
lastCount = images.count
}
if lastCount > images.count {
offset += marginAdjust
currentPage -= 1
lastCount = images.count
}
})
.gesture(DragGesture().onEnded { value in
if value.translation.width < 0 && currentPage < images.count - 1 {
withAnimation {
offset -= pageSize
currentPage += 1
}
}
if value.translation.width > 0 && currentPage > 0 {
withAnimation {
offset += pageSize
currentPage -= 1
}
}
})
.frame(width: size, height: size)
.clipped()
.fixedSize()
.zIndex(-1)
if images.count <= 6 && images.count > 1 {
HStack(spacing: 1) {
Spacer()
ForEach(0..<images.count, id: \.self) { i in
Circle()
.fill(i == currentPage ? Color(UIColor.systemGray) : Color(UIColor.systemGray3))
.frame(width: 20)
}
Spacer()
}
.frame(width: size)
.fixedSize()
} else if images.count > 1 {
Text("\(currentPage)/\(images.count)")
.font(.caption)
}
}
}
}
@diogoos
Copy link
Copy Markdown
Author

diogoos commented Apr 1, 2021

Demo implementation:

struct DemoView: View {
    @State var images: [UIImage] = ....

    var body: some View {
        HStack {
             VStack {
                 Text("Yosemite Park").font(.title)
                 Text("California").font(.headline)
             }.zIndex(2)

             ThumbnailSlideView(images: $recievedImages)
        }
    }
}

Preview:
simulator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment