Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Report

> The more information you provide, the faster we can help you.

⚠️ Select what you want - **a feature request** or **report a bug**. Please remove the section you aren't interested in.

## A feature request

### What do you want to add?

> Please describe what you want to add to the component.

### How should it look like?

> Please add images.

## Report a bug

### What did you do?

> Please replace this with what you did.

### What did you expect to happen?

> Please replace this with what you expected to happen.

### What happened instead?

> Please replace this with what happened instead.

### Your Environment

- Version of the component: _insert here_
- Swift version: _insert here_
- iOS version: _insert here_
- Device: _insert here_
- Xcode version: _insert here_
- If you use Cocoapods: _run `pod env | pbcopy` and insert here_
- If you use Carthage: _run `carthage version | pbcopy` and insert here_

### Project that demonstrates the bug

> Please add a link to a project we can download that reproduces the bug.
20 changes: 10 additions & 10 deletions Example/Koloda.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Koloda_Example" */;
buildPhases = (
0182469EE898CFC3334C577B /* Check Pods Manifest.lock */,
0182469EE898CFC3334C577B /* [CP] Check Pods Manifest.lock */,
607FACCC1AFB9204008FA782 /* Sources */,
607FACCD1AFB9204008FA782 /* Frameworks */,
607FACCE1AFB9204008FA782 /* Resources */,
64922D3147424C142700ED20 /* Embed Pods Frameworks */,
822E414921E8C1E4C57072A9 /* Copy Pods Resources */,
64922D3147424C142700ED20 /* [CP] Embed Pods Frameworks */,
822E414921E8C1E4C57072A9 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -209,44 +209,44 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
0182469EE898CFC3334C577B /* Check Pods Manifest.lock */ = {
0182469EE898CFC3334C577B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
64922D3147424C142700ED20 /* Embed Pods Frameworks */ = {
64922D3147424C142700ED20 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Koloda_Example/Pods-Koloda_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
822E414921E8C1E4C57072A9 /* Copy Pods Resources */ = {
822E414921E8C1E4C57072A9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
4 changes: 2 additions & 2 deletions Example/Koloda/BackgroundAnimationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class BackgroundAnimationViewController: UIViewController {

//MARK: IBActions
@IBAction func leftButtonTapped() {
kolodaView?.swipe(SwipeResultDirection.left)
kolodaView?.swipe(.left)
}

@IBAction func rightButtonTapped() {
kolodaView?.swipe(SwipeResultDirection.right)
kolodaView?.swipe(.right)
}

@IBAction func undoButtonTapped() {
Expand Down
21 changes: 0 additions & 21 deletions Koloda.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
C517E4F21D9D00520002D88F /* KolodaViewAnimatior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C517E4E81D9D00520002D88F /* KolodaViewAnimatior.swift */; };
C517E4F31D9D00520002D88F /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C517E4EA1D9D00520002D88F /* OverlayView.swift */; };
C517E4F41D9D00520002D88F /* SwipeResultDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C517E4EB1D9D00520002D88F /* SwipeResultDirection.swift */; };
C517E4F91D9D01920002D88F /* pop.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C517E4F81D9D01920002D88F /* pop.framework */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -35,7 +34,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C517E4F91D9D01920002D88F /* pop.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -144,7 +142,6 @@
C517E4A71D9CF9010002D88F /* Frameworks */,
C517E4A81D9CF9010002D88F /* Headers */,
C517E4A91D9CF9010002D88F /* Resources */,
C517E4F61D9D01120002D88F /* Carthage */,
);
buildRules = (
);
Expand Down Expand Up @@ -197,24 +194,6 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
C517E4F61D9D01120002D88F /* Carthage */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/Carthage/Build/iOS/pop.framework",
);
name = Carthage;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
C517E4A61D9CF9010002D88F /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Yalantis
Copyright (c) 2017 Yalantis

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
67 changes: 44 additions & 23 deletions Pod/Classes/KolodaView/KolodaView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ private let defaultBackgroundCardsTopMargin: CGFloat = 4.0
private let defaultBackgroundCardsScalePercent: CGFloat = 0.95
private let defaultBackgroundCardsLeftMargin: CGFloat = 8.0
private let defaultBackgroundCardFrameAnimationDuration: TimeInterval = 0.2
private let defaultAppearanceAnimationDuration: TimeInterval = 0.8

//Opacity values
private let defaultAlphaValueOpaque: CGFloat = 1.0
Expand Down Expand Up @@ -47,6 +48,7 @@ public protocol KolodaViewDelegate: class {
func kolodaShouldApplyAppearAnimation(_ koloda: KolodaView) -> Bool
func kolodaShouldMoveBackgroundCard(_ koloda: KolodaView) -> Bool
func kolodaShouldTransparentizeNextCard(_ koloda: KolodaView) -> Bool
func kolodaOpacityForNextCard(_ koloda: KolodaView, at index: Int) -> CGFloat
func koloda(_ koloda: KolodaView, draggedCardWithPercentage finishPercentage: CGFloat, in direction: SwipeResultDirection)
func kolodaDidResetCard(_ koloda: KolodaView)
func kolodaSwipeThresholdRatioMargin(_ koloda: KolodaView) -> CGFloat?
Expand All @@ -66,6 +68,7 @@ public extension KolodaViewDelegate {
func kolodaShouldApplyAppearAnimation(_ koloda: KolodaView) -> Bool { return true }
func kolodaShouldMoveBackgroundCard(_ koloda: KolodaView) -> Bool { return true }
func kolodaShouldTransparentizeNextCard(_ koloda: KolodaView) -> Bool { return true }
func kolodaOpacityForNextCard(_ koloda: KolodaView, at index: Int) -> CGFloat { return defaultAlphaValueSemiTransparent }
func koloda(_ koloda: KolodaView, draggedCardWithPercentage finishPercentage: CGFloat, in direction: SwipeResultDirection) {}
func kolodaDidResetCard(_ koloda: KolodaView) {}
func kolodaSwipeThresholdRatioMargin(_ koloda: KolodaView) -> CGFloat? { return nil}
Expand All @@ -82,6 +85,8 @@ open class KolodaView: UIView, DraggableCardDelegate {
public var alphaValueSemiTransparent = defaultAlphaValueSemiTransparent
public var shouldPassthroughTapsWhenNoVisibleCards = false

public var appearanceAnimationDuration = defaultAppearanceAnimationDuration

public weak var dataSource: KolodaViewDataSource? {
didSet {
setupDeck()
Expand Down Expand Up @@ -129,7 +134,7 @@ open class KolodaView: UIView, DraggableCardDelegate {
nextCardView.isUserInteractionEnabled = isTop
nextCardView.alpha = alphaValueOpaque
if shouldTransparentizeNextCard && !isTop {
nextCardView.alpha = alphaValueSemiTransparent
nextCardView.alpha = self.cardAlphaTransparent(at: index)
}
visibleCards.append(nextCardView)
isTop ? addSubview(nextCardView) : insertSubview(nextCardView, belowSubview: visibleCards[index - 1])
Expand Down Expand Up @@ -222,7 +227,7 @@ open class KolodaView: UIView, DraggableCardDelegate {
//For fully visible next card, when moving top card
if shouldTransparentizeNextCard {
if index == 1 {
card.alpha = alphaValueSemiTransparent + (alphaValueOpaque - alphaValueSemiTransparent) * fraction
card.alpha = alphaValueSemiTransparent + (alphaValueOpaque - self.cardAlphaTransparent(at: index)) * fraction
}
}
}
Expand All @@ -235,10 +240,10 @@ open class KolodaView: UIView, DraggableCardDelegate {
isUserInteractionEnabled = false
animating = true

animator.animateAppearanceWithCompletion { [weak self] _ in
animator.animateAppearance(duration: appearanceAnimationDuration, completion: { [weak self] _ in
self?.isUserInteractionEnabled = true
self?.animating = false
}
})
}

public func applyAppearAnimationIfNeeded() {
Expand Down Expand Up @@ -284,7 +289,7 @@ open class KolodaView: UIView, DraggableCardDelegate {
for index in 1..<_self.visibleCards.count {
let card = _self.visibleCards[index]
if _self.shouldTransparentizeNextCard {
card.alpha = index == 0 ? _self.alphaValueOpaque : _self.alphaValueSemiTransparent
card.alpha = index == 0 ? _self.alphaValueOpaque : _self.cardAlphaTransparent(at: index)
}
}
}
Expand Down Expand Up @@ -324,7 +329,14 @@ open class KolodaView: UIView, DraggableCardDelegate {
visibleCards.removeAll(keepingCapacity: true)
}

// MARK: Actions
private func cardAlphaTransparent(at index: Int) -> CGFloat {

let alphaTransparent: CGFloat = self.delegate != nil ? self.delegate!.kolodaOpacityForNextCard(self, at: index) : alphaValueSemiTransparent
return alphaTransparent
}


//MARK: Actions
private func swipedAction(_ direction: SwipeResultDirection) {
animating = true
visibleCards.removeFirst()
Expand Down Expand Up @@ -383,7 +395,7 @@ open class KolodaView: UIView, DraggableCardDelegate {
var animationCompletion: ((Bool) -> Void)? = nil
if index != 0 {
if shouldTransparentizeNextCard {
currentCard.alpha = alphaValueSemiTransparent
currentCard.alpha = cardAlphaTransparent(at: index)
}
} else {
animationCompletion = { finished in
Expand Down Expand Up @@ -443,8 +455,8 @@ open class KolodaView: UIView, DraggableCardDelegate {

for (index, card) in visibleCards.dropFirst().enumerated() {
if shouldTransparentizeNextCard {
card.alpha = alphaValueSemiTransparent
}
card.alpha = cardAlphaTransparent(at: index)
}
card.isUserInteractionEnabled = false

let cardParameters = backgroundCardParametersForFrame(frameForCard(at: index + 1))
Expand All @@ -457,19 +469,18 @@ open class KolodaView: UIView, DraggableCardDelegate {
)
}
}

private func loadMissingCards(_ missingCardsCount: Int) {
guard missingCardsCount > 0 else {
return
}
guard missingCardsCount > 0 else { return }

let cardsToAdd = min(missingCardsCount, countOfCards - currentCardIndex)
let startIndex = visibleCards.count
let endIndex = startIndex + cardsToAdd - 1

for index in startIndex...endIndex {
let nextCardView = generateCard(frameForTopCard())
layoutCard(nextCardView, at: index)
nextCardView.alpha = shouldTransparentizeNextCard ? alphaValueSemiTransparent : alphaValueOpaque
nextCardView.alpha = shouldTransparentizeNextCard ? cardAlphaTransparent(at: index) : alphaValueOpaque

visibleCards.append(nextCardView)
configureCard(nextCardView, at: currentCardIndex + index)
Expand Down Expand Up @@ -520,8 +531,12 @@ open class KolodaView: UIView, DraggableCardDelegate {
reconfigureCards()
}
}

public func swipe(_ direction: SwipeResultDirection) {

public func swipe(_ direction: SwipeResultDirection, force: Bool = false) {
let shouldSwipe = delegate?.koloda(self, shouldSwipeCardAt: currentCardIndex, in: direction) ?? true
guard force || shouldSwipe else {
return
}

let validDirection = delegate?.koloda(self, allowedDirectionsForIndex: currentCardIndex).contains(direction) ?? true
guard validDirection else { return }
Expand All @@ -531,8 +546,10 @@ open class KolodaView: UIView, DraggableCardDelegate {
animating = true

if visibleCards.count > 1 {
let nextCard = visibleCards[1]
nextCard.alpha = shouldTransparentizeNextCard ? alphaValueSemiTransparent : alphaValueOpaque
for i in 1..<visibleCards.count {
let nextCard = visibleCards[i]
nextCard.alpha = shouldTransparentizeNextCard ? cardAlphaTransparent(at: i) : alphaValueOpaque
}
}
frontCard.swipe(direction)
frontCard.delegate = nil
Expand Down Expand Up @@ -575,7 +592,7 @@ open class KolodaView: UIView, DraggableCardDelegate {
insertSubview(card, at: visibleCards.count - 1)
} else {
card.isUserInteractionEnabled = false
card.alpha = shouldTransparentizeNextCard ? alphaValueSemiTransparent : alphaValueOpaque
card.alpha = shouldTransparentizeNextCard ? cardAlphaTransparent(at: visibleCardIndex) : alphaValueOpaque
insertSubview(card, belowSubview: visibleCards[visibleCardIndex - 1])
}
layoutCard(card, at: visibleCardIndex)
Expand Down Expand Up @@ -637,13 +654,17 @@ open class KolodaView: UIView, DraggableCardDelegate {

// MARK: Cards managing - Deletion

private func proceedDeletionInRange(_ range: CountableClosedRange<Int>) {
private func proceedDeletionInRange(_ range: CountableClosedRange<Int>, animated: Bool) {
let deletionIndexes = [Int](range)
deletionIndexes.sorted { $0 > $1 }.forEach { deletionIndex in
let visibleCardIndex = deletionIndex - currentCardIndex
let card = visibleCards[visibleCardIndex]
card.delegate = nil
card.swipe(.right)
if animated {
animator.removeCardAnimation(card: card)
} else {
card.removeFromSuperview()
}
visibleCards.remove(at: visibleCardIndex)
}
}
Expand All @@ -658,13 +679,13 @@ open class KolodaView: UIView, DraggableCardDelegate {
countOfCards = dataSource.kolodaNumberOfCards(self)
let visibleIndexes = [Int](indexRange).filter { $0 >= currentCardIndex && $0 < currentCardIndex + countOfVisibleCards }
if !visibleIndexes.isEmpty {
proceedDeletionInRange(visibleIndexes[0]...visibleIndexes[visibleIndexes.count - 1])
proceedDeletionInRange(visibleIndexes[0]...visibleIndexes[visibleIndexes.count - 1], animated: animated)
}
currentCardIndex -= Array(indexRange).filter { $0 < currentCardIndex }.count
loadMissingCards(missingCardsCount())
layoutDeck()
for (index, card) in visibleCards.enumerated() {
card.alpha = shouldTransparentizeNextCard && index != 0 ? alphaValueSemiTransparent : alphaValueOpaque
card.alpha = shouldTransparentizeNextCard && index != 0 ? cardAlphaTransparent(at: index) : alphaValueOpaque
card.isUserInteractionEnabled = index == 0
}
animating = false
Expand Down
Loading