一个折叠牌样式的可滑动 UI 效果实现

本文最后更新于 2021年4月4日 晚上

当前正在做一个普通的商场项目, 不过 UI 设计师突发奇想设计了一个秒杀界面, 里面需要一个卡片视图, 卡片可以左右滑动, 类似折叠牌的效果. 这里正好找到一个库叫 Koloda, 可以仿照它来实现折叠牌, 顺便记录下来整个实现过程.

类似折叠牌视图

当前的需求是实现一个类似一沓折叠牌的 UI, 可以左右滑动, 每一张牌就是一个秒杀活动的内容页. 找到 Koloda 库, 看到它的实现比较接近 UI 设计, 故仿照它来实现.

并且看到这个的关键字都是叫 Tinder 或者是 Tinder like, 记下方便搜索, 果然在谷歌上可以找到很多这样的文章.

目前的 UI 设计就是类似这篇文章所描述的效果. 普通的代码实现可以看看Github 上的这里.

先来看是否可以通过库来实现, 如果可以直接使用库, 否则就参考文章来手动实现.

使用 Koloda 库实现

先来看利用 Koloda 库来实现的过程, 这里使用 Carthage 作为依赖管理工具(因为库中有些内容在 pod 下编译不通过, 且 pod 识别到版本是 4.4, 没有最新的).

使用 Carthage 时, 需要将里面额外携带的 pop 动画库也链接进工程.

如果要使用 Pod, 则引入的时候这样来: pod 'Koloda', '~> 4.5'.

而实际上实现也是非常简单, 引入库之后直接使用即可, 自定义视图内容可以在数据源方法 viewForCardAt 中指定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import UIKit
import Koloda
import SnapKit

private var numberOfCards: Int = 5

class ViewController: UIViewController {

private var kolodaView: KolodaView!

private var dataSource: [String] = {
var array = [String]()
for index in 0..<numberOfCards {
array.append("Card_like_\(index + 1)")
}

return array
}()

// MARK: Lifecycle

override func viewDidLoad() {
super.viewDidLoad()

kolodaView = KolodaView()
kolodaView.dataSource = self
kolodaView.delegate = self

view.addSubview(kolodaView)
kolodaView.snp.makeConstraints {
$0.center.equalToSuperview()
$0.width.height.equalToSuperview().multipliedBy(0.6)
}
}
}

// MARK: KolodaViewDelegate

extension ViewController: KolodaViewDelegate {

func kolodaDidRunOutOfCards(_ koloda: KolodaView) {
let position = kolodaView.currentCardIndex
for i in 1...4 {
dataSource.append("Card_like_\(i)")
}
kolodaView.insertCardAtIndexRange(position..<position + 4, animated: true)
}

func koloda(_ koloda: KolodaView, didSelectCardAt index: Int) {
UIApplication.shared.openURL(URL(string: "https://yalantis.com/")!)
}

}

// MARK: KolodaViewDataSource

extension ViewController: KolodaViewDataSource {

func kolodaNumberOfCards(_ koloda: KolodaView) -> Int {
return dataSource.count
}

func kolodaSpeedThatCardShouldDrag(_ koloda: KolodaView) -> DragSpeed {
return .default
}

func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let cardView = UIView()
cardView.backgroundColor = UIColor.random()
return cardView
}

func koloda(_ koloda: KolodaView, viewForCardOverlayAt index: Int) -> OverlayView? {
return nil
}
}

故只需要按需实现内容视图即可, 并且是否循环也可以直接控制, 效果如下所示:

顺便给出上述随机颜色的实现代码, 方便直接验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
extension CGFloat {
static func random() -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UInt32.max)
}
}

extension UIColor {
static func random() -> UIColor {
return UIColor(red: .random(),
green: .random(),
blue: .random(),
alpha: 1.0)
}
}

代码手动实现

需要好好看看这里面的原理, 特别是 Koloda 库以及之前说的那几篇文章(搜索一下关键字看看有没有更多优质文章), 可以学到很多东西应该, 另外可以看看这篇文章讲许多 iOS 效果实现, 这样可以对视图的实现有一个更深层次的认识.


一个折叠牌样式的可滑动 UI 效果实现
https://blog.rayy.top/2018/09/25/2019-7-cardView/
作者
貘鸣
发布于
2018年9月25日
许可协议