🃏 CardStack

Swift Version License Platform

一个易于使用的 SwiftUI 视图,用于在 iOS、macOS 和 watchOS 上创建类似 Tinder 的卡片效果。

Alt text

安装

Xcode 11 及 Swift Package Manager

在 Xcode 或 SPM package.swift 文件中使用包仓库 URL:https://github.com/dadalar/SwiftUI-CardStackView.git

CocoaPods

CardStack 可以通过 CocoaPods 获得。 要安装它,只需将以下行添加到您的 Podfile 中

pod "SwiftUICardStack"

用法

此组件的用法类似于 SwiftUI 的 List。 一个基本的实现如下所示

@State var cards: [Card] // This is the data to be shown in CardStack

CardStack(
  direction: LeftRight.direction, // See below for directions
  data: cards,
  onSwipe: { card, direction in // Closure to be called when a card is swiped.
    print("Swiped \(card) to \(direction)")
  },
  content: { card, direction, isOnTop in // View builder function
    CardView(card)
  }
)

方向

CardStack 需要知道哪些方向可用,以及如何将滑动角度转换为该方向。 这是一个有意识的决定,旨在使组件易于扩展,同时保持类型安全。 需要传递给 CardStack 初始化器的参数是一个简单的 (Double) -> Direction? 函数。 此处的 Double 输入是角度,以度为单位,其中 0 指向上,180 指向下。 Direction 是一种泛型类型,这意味着此库的用户可以使用自己的类型。 从此函数返回 nil 以指示该角度不是有效方向(用户将无法滑动到该方向)。

有以下预定义方向(LeftRightFourDirectionsEightDirections),并且每个方向都定义了一个 direction(double:) 函数,该函数可以在 CardStack 初始化器中使用。 您可以查看示例项目以了解自定义方向的实现。

配置

可以使用 SwiftUI 的标准环境值配置 CardStack。 它可以直接在 CardStack 上或其封装视图上设置。

CardStack(
  // Initialize
)
.environment(\.cardStackConfiguration, CardStackConfiguration(
  maxVisibleCards: 3,
  swipeThreshold: 0.1,
  cardOffset: 40,
  cardScale: 0.2,
  animation: .linear
))

用例:追加项目

加载新数据并追加到堆栈非常容易。 只需确保 data 属性标记为 @State,然后您可以追加到数组。 请查看示例项目以了解实际案例。

struct AddingCards: View {
  @State var data: [Person] // Some initial data

  var body: some View {
    CardStack(
      direction: LeftRight.direction,
      data: data,
      onSwipe: { _, _ in },
      content: { person, _, _ in
        CardView(person: person)
      }
    )
    .navigationBarItems(trailing:
      Button(action: {
        self.data.append(contentsOf: [ /* some new data */ ])
      }) {
        Text("Append")
      }
    )
  }
}

用例:重新加载项目

由于该组件保留当前卡片的内部索引,因此更改数据的顺序或在当前项目之前添加/删除项目将破坏该组件。 如果要替换整个数据,则需要通过更改组件的 id 来强制 SwiftUI 重构该组件。 请查看示例项目以了解实际案例。

struct ReloadCards: View {
  @State var reloadToken = UUID()
  @State var data: [Person] = Person.mock.shuffled()

  var body: some View {
    CardStack(
      direction: LeftRight.direction,
      data: data,
      onSwipe: { _, _ in },
      content: { person, _, _ in
        CardView(person: person)
      }
    )
    .id(reloadToken)
    .navigationBarItems(trailing:
      Button(action: {
        self.reloadToken = UUID()
        self.data = Person.mock.shuffled()
      }) {
        Text("Reload")
      }
    )
  }
}

作者

Deniz Adalar, me@dadalar.net

许可证

CardStack 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。