And*_*rew 9 macos swift swiftui
Target 是具有以下行为的修改:
(但只有 2 个按钮 - 左侧 1 个,右侧 1 个)
行为:
短滑显示按钮并让用户能够点击它。
强长滑动按下按钮。
能够使用 2 指手势
最小可重现示例:
import SwiftUI
public extension View {
func SwiperizeItem(closureL: @escaping () -> (), closureR: @escaping () -> ()) -> some View
{
self.modifier( SwiperizeItemModifier(closureL: closureL, closureR: closureR) )
}
}
struct SwiperizeItemModifier: ViewModifier {
@State var dragOffset = CGSize.zero
@State var offset1Shown = CGSize(width: 100, height: 0)
@State var offset1Click = CGSize(width: 250, height: 0)
@State var offset2Shown = CGSize(width: -100, height: 0)
@State var offset2Click = CGSize(width: -250, height: 0)
@State var BackL = Color.green
@State var BackR = Color.red
@State var ForeColorL = Color.white
@State var ForeColorR = Color.white
@State var closureL: () -> Void
@State var closureR: () -> Void
func body(content: Content) -> some View {
HStack{
Button(action: { closureL() } ) {
Text("Left")
.foregroundColor(ForeColorL)
}
.background(BackL)
.frame(maxWidth: dragOffset.width > 0 ? dragOffset.width : 0)
.fixedSize()
content
//.padding([.leading, .trailing], 20)
.animation(.spring())
.offset(x: self.dragOffset.width)
.gesture(DragGesture()
.onChanged(){
value in
self.dragOffset = value.translation
}
.onEnded(){
value in
if ( dragOffset.width > 0 ) {
if ( dragOffset.width < offset1Shown.width) {
self.dragOffset = .zero
}
else if ( dragOffset.width > offset1Shown.width && dragOffset.width < offset1Click.width ) {
self.dragOffset = offset1Shown
}
else if ( dragOffset.width > offset1Click.width ) {
self.dragOffset = .zero
closureR()
}
}
else {
if ( dragOffset.width > offset2Shown.width) {
self.dragOffset = .zero
}
else if ( dragOffset.width < offset2Shown.width && dragOffset.width > offset2Click.width ) {
self.dragOffset = offset2Shown
}
else if ( dragOffset.width < offset2Click.width ) {
self.dragOffset = .zero
closureL()
}
}
}
)
}
}
}
// ____________________
struct GuestureItem_Previews: PreviewProvider {
static var previews: some View {
Group {
Text("Hello")
.padding(.all, 30)
.background( Color( NSColor.red ) )
.SwiperizeItem(closureL: { print("click left") }, closureR: { print("click right") })
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以......我的问题是:
我认为该解决方案可能与 SwiftUI 组件的新版本有关:
LazyHGrid或OutlineGroup. https://developer.apple.com/videos/play/wwdc2020/10031
.onDelete() 对我来说不是一个解决方案,因为它不可能做 2 个侧按钮并且不可能编辑“删除”文本
不幸的是,到目前为止还没有任何原生的 SwiftUI 解决方案(截至 SwiftUI 2 beta)。
You can make your custom swipe actions using UIKit and wrap them in UIViewRepresentable.
Some solutions (you may have seen them already):
Or you can just use a library instead (at least until a native solution is developed).
Some libraries:
If you want to implement simultaneous swipe gesture you need to use UIViewRepresentable again:
Summing up
只要您不想为删除按钮创建自定义 UI,您就可以利用 SwiftUI 并使用所有内置功能。
ForEach有一个名为 的修饰符.onDelete,它为您提供一个IndexSet. 这表示当用户滑动时应删除的行。现在,如果我们实现必要的逻辑并将其包装在动画块中,一切都会按需要进行。
struct ContentView: View {
@State var cars = ["Tesla Model 3", "BMW i3", "Roadster", "Cybertruck", "Agera Koenigsegg", "Rimac Concept One"]
var body: some View {
NavigationView {
List {
ForEach(cars, id: \.self) { car in
Text(car)
}
.onDelete { indexSet in
withAnimation {
cars.remove(atOffsets: indexSet)
}
}
}
.navigationTitle("My Cars")
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:.onDelete修饰符不能与 with 一起使用List,只能应用于 on ForEach。
截至目前,SwiftUI 不支持为多个手指创建手势。UIViewRepresentable唯一的解决方案是与 结合使用UIPanGestureRecognizer。然后您可以将其设置minimumNumberOfTouches为 2 根手指。
Apple 开发者论坛的这篇文章展示了如何通过简单的 2 根手指点击手势实现类似的效果,但滑动的想法和概念非常相似,并且已经在上面进行了解释。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
1711 次 |
| 最近记录: |