Skip to content

Commit

Permalink
Merge pull request #9 from juandahurt/collection-card
Browse files Browse the repository at this point in the history
feature: add missing collection card behavior
  • Loading branch information
juandahurt authored May 28, 2022
2 parents ce51882 + dc3476d commit ec9c82d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 21 deletions.
23 changes: 15 additions & 8 deletions PuraceDemo/PuraceDemo/Examples/CollectionCardExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@ import SwiftUI

struct CollectionCardExample: View {
var body: some View {
Text("`PuraceCollectionCardView(cards: ...)`")
.padding()
PuraceCollectionCardView(cards: [
MockCard("https://www.biografiasyvidas.com/biografia/c/fotos/caldas_francisco_jose_2.jpg"),
MockCard("https://upload.wikimedia.org/wikipedia/commons/a/ac/Froil%C3%A1n_Largacha_Hurtado.jpg"),
MockCard("https://upload.wikimedia.org/wikipedia/commons/8/86/Camilo_Torres_y_Tenorio.jpg")
])
Spacer()
ScrollView {
Text("`PuraceCollectionCardView(cards: ...)`")
.padding()
PuraceCollectionCardView(
firstCardSize: .init(width: UIScreen.main.bounds.width * 0.6, height: UIScreen.main.bounds.width * 0.7),
cards: [
MockCard("https://www.biografiasyvidas.com/biografia/c/fotos/caldas_francisco_jose_2.jpg"),
MockCard("https://upload.wikimedia.org/wikipedia/commons/a/ac/Froil%C3%A1n_Largacha_Hurtado.jpg"),
MockCard("https://upload.wikimedia.org/wikipedia/commons/8/86/Camilo_Torres_y_Tenorio.jpg")
]
) { card in
print("selected card: \(card)")
}
Spacer()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ public struct PuraceCollectionCardView: View {
@State var dragOffset: CGSize = .zero
@State var dragOpacity: Double = 1

private let firstCardSize = CGSize(width: 220, height: 300)
private let firstCardSize: CGSize
private let onCardTapped: ((PuraceCollectionCardData) -> Void)?

@State var cards: [PuraceCollectionCardData]
let numberOfCards: Int

public init(cards: [PuraceCollectionCardData]) {
public init(firstCardSize: CGSize, cards: [PuraceCollectionCardData], onCardTapped: ((PuraceCollectionCardData) -> Void)? = nil) {
self.firstCardSize = firstCardSize
self.cards = cards
self.numberOfCards = cards.count
self.onCardTapped = onCardTapped
}

func next() {
Expand All @@ -32,9 +35,20 @@ public struct PuraceCollectionCardView: View {
guard index != numberOfCards - 1 else {
return firstCardSize
}
let maxWidth: CGFloat
let maxHeight: CGFloat
if index == numberOfCards - 2 {
maxWidth = firstCardSize.width
maxHeight = firstCardSize.height
} else {
maxWidth = firstCardSize.width - CGFloat(numberOfCards - index - 1) * 10
maxHeight = firstCardSize.height - CGFloat(numberOfCards - index - 1) * 10
}
let possibleWidth = firstCardSize.width - CGFloat(numberOfCards - index) * 10 - dragOffset.width * 0.7
let possibleHeight = firstCardSize.height - CGFloat(numberOfCards - index) * 10 - dragOffset.width * 0.7
return CGSize(
width: firstCardSize.width - CGFloat(numberOfCards - index) * 10,
height: firstCardSize.height - CGFloat(numberOfCards - index) * 10
width: min(possibleWidth, maxWidth),
height: min(possibleHeight, maxHeight)
)
}

Expand All @@ -52,6 +66,19 @@ public struct PuraceCollectionCardView: View {
return 1.0 - 1.0 / Double(numberOfCards - index)
}

func getHorizontalOffset(forCardAt index: Int) -> CGFloat {
guard index != numberOfCards - 1 else {
return 0
}
let minOffset: CGFloat
if index == numberOfCards - 2 {
minOffset = 0
} else {
minOffset = CGFloat((numberOfCards - index - 1) * 15)
}
return max(CGFloat((numberOfCards - index) * 15) + dragOffset.width * 0.5, minOffset)
}

func card(at index: Int) -> some View {
Group {
if cards.isEmpty {
Expand All @@ -74,16 +101,16 @@ public struct PuraceCollectionCardView: View {
.frame(width: getSize(at: index).width, height: getSize(at: index).height)
.cornerRadius(5)
.opacity(index == cards.count - 1 ? dragOpacity : 1)
.offset(x: CGFloat(index == numberOfCards - 1 ? 0 : (numberOfCards - index) * 10) , y: 0)
.offset(x: getHorizontalOffset(forCardAt: index), y: 0)
.offset(x: index == numberOfCards - 1 ? dragOffset.width : .zero, y: .zero)
.onTapGesture {
if index == numberOfCards - 1 {
// user can only touch the top card!

onCardTapped?(cards[index])
}
}
.simultaneousGesture(
DragGesture(minimumDistance: 0, coordinateSpace: .global)
DragGesture(minimumDistance: 10, coordinateSpace: .global)
.onChanged({ value in
if value.translation.width < 0 && index == numberOfCards - 1 {
dragOffset = value.translation
Expand All @@ -105,12 +132,14 @@ public struct PuraceCollectionCardView: View {
}

public var body: some View {
HStack(alignment: .center) {
ZStack(alignment: .trailing) {
ForEach(0..<numberOfCards) { index in
card(at: index)
GeometryReader { reader in
HStack(alignment: .center) {
ZStack(alignment: .trailing) {
ForEach(0..<numberOfCards) { index in
card(at: index)
}
}
}
}.frame(width: UIScreen.main.bounds.width, height: 300)
}.frame(width: UIScreen.main.bounds.width, height: firstCardSize.height)
}
}
}

0 comments on commit ec9c82d

Please sign in to comment.