Skip to content

Instantly share code, notes, and snippets.

@vladimir-anisimov
Created April 5, 2021 09:05
Show Gist options
  • Save vladimir-anisimov/d81dd72ea4bb27abe980d29cffad15ea to your computer and use it in GitHub Desktop.
Save vladimir-anisimov/d81dd72ea4bb27abe980d29cffad15ea to your computer and use it in GitHub Desktop.
UICollectionViewCell with swipe support
import UIKit
class SwipeableCell: UICollectionViewCell, UIGestureRecognizerDelegate {
var maxSwipeOffset = CGFloat(200)
private var pan: UIPanGestureRecognizer!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
self.contentView.backgroundColor = UIColor.gray
self.backgroundColor = UIColor.red
pan = UIPanGestureRecognizer(target: self, action: #selector(onPan(_:)))
pan.delegate = self
self.addGestureRecognizer(pan)
}
@objc func onPan(_ pan: UIPanGestureRecognizer) {
switch pan.state {
case .began:
beganSwipeGesture(pan)
case .changed:
changeSwipeGesture(pan)
case .ended:
endSwipeGesture(pan)
default:
return
}
}
private func cancelGesture(_ gesture: UIPanGestureRecognizer) {
gesture.isEnabled = false
self.isUserInteractionEnabled = false
self.isUserInteractionEnabled = true
gesture.isEnabled = true
}
private func beganSwipeGesture(_ gesture: UIPanGestureRecognizer) {
if contentView.frame.origin.x != 0 {
UIView.animate(withDuration: 0.2) {
self.contentView.frame.origin.x = 0
}
cancelGesture(gesture)
} else {
let translation = pan.translation(in: self)
if translation.x > 0 {
cancelGesture(gesture)
}
}
}
private func endSwipeGesture(_ gesture: UIPanGestureRecognizer) {
if self.contentView.frame.origin.x >= -self.maxSwipeOffset / 2 {
UIView.animate(withDuration: 0.2) {
self.contentView.frame.origin.x = 0
}
} else {
UIView.animate(withDuration: 0.2) {
self.contentView.frame.origin.x = -self.maxSwipeOffset
}
}
}
private func changeSwipeGesture(_ gesture: UIPanGestureRecognizer) {
let translation = pan.translation(in: self)
if translation.x < 0 {
if translation.x >= -maxSwipeOffset {
self.contentView.frame.origin.x = translation.x
}
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment