随着 SwiftUI 2.0 的不断完善,我觉得是时候将我的 App 做一个较大的升级了。之前一直想在 App 中实现类似 iOS 邮件程序那样优雅的侧滑菜单效果,在网上也找了一下,实现的较好的是适用于 UIKit 的,基本上没有能够很好的适配 SwiftUI 的项目库。最终自己在 Xcode 12 实现了一个。
SwipeCell 是一个用 Swift 5.3 开发的 SwiftUI 库。目标是为了实现类似 iOS Mail 程序实现的左右滑动菜单功能。SwipeCell 需要 XCode 12 ,iOS 14
配置 Button
Swift
let button1 = SwipeCellButton(buttonStyle: .titleAndImage,
title: "Mark",
systemImage: "bookmark",
titleColor: .white,
imageColor: .white,
view: nil,
backgroundColor: .green,
action: {bookmark.toggle()},
feedback:true
)
//你可以将按钮设置成任意 View 从而实现更复杂的设计以及动态效果
let button3 = SwipeCellButton(buttonStyle: .view, title:"",systemImage: "", view: {
AnyView(
Group{
if unread {
Image(systemName: "envelope.badge")
.foregroundColor(.white)
.font(.title)
}
else {
Image(systemName: "envelope.open")
.foregroundColor(.white)
.font(.title)
}
}
)
}, backgroundColor: .orange, action: {unread.toggle()}, feedback: false)
配置 Slot
Swift
let slot1 = SwipeCellSlot(slots: [button2,button1])
let slot2 = SwipeCellSlot(slots: [button4], slotStyle: .destructive, buttonWidth: 60)
let slot3 = SwipeCellSlot(slots: [button2,button1],slotStyle: .destructiveDelay)
装配
Swift
cellView()
.swipeCell(cellPosition: .left, leftSlot: slot4, rightSlot: nil)
更多的配置选项
Swift
cellView()
.swipeCell(cellPosition: .both,
leftSlot: slot1,
rightSlot: slot1 ,
swipeCellStyle: SwipeCellStyle(
alignment: .leading,
dismissWidth: 20,
appearWidth: 20,
destructiveWidth: 240,
vibrationForButton: .error,
vibrationForDestructive: .heavy,
autoResetTime: 3)
)
滚动列表自动消除
For List
Swift
List{
...
}
.dismissSwipeCell()
}
For single cell in ScrollView
Swift
ScrollView{
VStack{
Text("Mail Title")
.dismissSwipeCellForScrollView()
Text("Mail Content")
....
}
.frame(maxWidth:.infinity,maxHeight: .infinity)
}
.swipeCell(cellPosition: .both, leftSlot: leftSlot, rightSlot: rightSlot,clip: false)
For LazyVStack in ScrollView
Swift
ScrollView{
LazyVStack{
ForEach(lists,id:\.self){ item in
Text("Swipe in scrollView:\(item)")
.frame(height:80)
.swipeCell(cellPosition: .both, leftSlot:slot, rightSlot: slot)
.dismissSwipeCellForScrollViewForLazyVStack()
}
}
dismissSwipeCell
在 editmode 下支持选择dismissSwipeCellForScrollView
用于 ScrollView, 通常用于只有一个 Cell 的场景,比如说 Mail 中的邮件内容显示。参看 Demo 中的演示dismissSwipeCellForScrollViewForLazyVStack
用于 ScrollView 中使用 LazyVStack 场景。个别时候会打断滑动菜单出现动画。个人觉得如无特别需要还是使用 List 代替 LazyVStack 比较好。
由于 SwiftUI 没有很好的方案能够获取滚动状态,所以采用了 Introspect 实现的上述功能。
destructiveDelay
形式的 button,需要在 action 中添加 dismissDestructiveDelayButton () 已保证在 alter 执行后,Cell 复位。
当前问题
- 动画细节仍然不足
- EditMode 模式下仍有不足
欢迎多提宝贵意见
SwipeCell is available under the MIT license.