与分段选取器匹配的SwiftUI视图转换

与分段选取器匹配的SwiftUI视图转换,swift,swiftui,swiftui-animation,Swift,Swiftui,Swiftui Animation,是否可以有三个(多于2个!)视图,根据选取器和分段选取样式()从侧面设置动画 拾取程序中只有2个项目会使作业处于静态状态,因此在第一个视图上有一个.transition(.move(edge:.leading)),在最后一个视图上有一个.transition(.move(edge:.training))就足够了。但是超过2个呢 也许有一种方法可以使转换的边缘:…参数动态设置为.leading或.training,具体取决于绑定的新值是大于还是小于当前值 我创建了以下草图,以演示使用不同过渡的相同

是否可以有三个(多于2个!)视图,根据
选取器
分段选取样式()
从侧面设置动画

拾取程序中只有2个项目会使作业处于静态状态,因此在第一个视图上有一个
.transition(.move(edge:.leading))
,在最后一个视图上有一个
.transition(.move(edge:.training))
就足够了。但是超过2个呢

也许有一种方法可以使转换的
边缘:…
参数动态设置为
.leading
.training
,具体取决于绑定的新值是大于还是小于当前值

我创建了以下草图,以演示使用不同过渡的相同视图(视图2)的问题,这取决于选择了右侧还是左侧的视图。请仅将此视为一个示例,问题不仅限于三个部分,也不限于中间视图,也不限于消失的过渡等


更新秘密在于确保过渡启动动画,并在启动之前告诉过渡方向。尝试一下:

class TabControllerContext : ObservableObject {
    @Published var selected = panels.one { didSet {
        if previous != selected {
            insertion = selected.makeMove(previous)
            removal = previous.makeMove(selected)

            withAnimation {
                trigger = selected
                previous = selected
            }
        }
    }}
    
    @Published var trigger = panels.one
    @Published var previous = panels.one
    var insertion : AnyTransition = .move(edge: .leading)
    var removal : AnyTransition = .move(edge: .trailing)
}

struct TabsWithTransitionsView: View {
    @EnvironmentObject var context : TabControllerContext
    
    var body: some View {
        VStack {
            Picker("Select Panel", selection: $context.selected) {
                ForEach(panels.allCases) { panel in
                    panel.label.tag(panel)
                }
            }.pickerStyle(SegmentedPickerStyle())
            
            ForEach(panels.allCases) { panel in
                if context.trigger == panel {
                    panel.label
                        .background(panel.color)
                        .transition(.asymmetric(insertion: context.insertion, removal: context.removal))
                }
            }
        }
    }
}

enum panels : Int, CaseIterable, Identifiable {
    case one = 1
    case two = 2
    case three = 3
    
    var label : some View {
        switch self {
        case .one:
            return Label("Tab One", systemImage: "1.circle")
        case .two:
            return Label("Tab Two", systemImage: "2.square")
        case .three:
            return Label("Tab Three", systemImage: "asterisk.circle")
        }
    }
    
    var color : Color {
        switch self {
        case .one: return Color.red.opacity(0.5)
        case .two: return Color.green.opacity(0.5)
        case .three: return Color.blue.opacity(0.5)
        }
    }
    
    func makeMove(_ otherPanel: panels) -> AnyTransition {
        return otherPanel.rawValue < self.rawValue ? .move(edge: .trailing) : .move(edge: .leading)
    }
    
    // so the enum can be indentified when enumerated
    var id : Int { self.rawValue }
}

struct TabsWithTransitionsView_Previews: PreviewProvider {
    static var previews: some View {
        TabsWithTransitionsView().environmentObject(TabControllerContext())
    }
}
类选项卡ControllerContext:observeObject{
@已发布的var selected=panels.one{didSet{
如果上一个!=选中{
插入=选定。makeMove(上一个)
删除=上一个.makeMove(选中)
动画片{
触发器=已选择
上一个=已选择
}
}
}}
@已发布的var触发器=panels.one
@已发布变量previous=panels.one
变量插入:AnyTransition=.move(边:。前导)
移除变量:AnyTransition=.move(边缘:。尾部)
}
结构选项卡SwithTransitionView:视图{
@环境对象变量上下文:TabControllerContext
var body:一些观点{
VStack{
选择器(“选择面板”,选择:$context.selected){
ForEach(panels.allCases){panel in
panel.label.tag(面板)
}
}.pickerStyle(SegmentedPickerStyle())
ForEach(panels.allCases){panel in
如果context.trigger==面板{
面板标签
.背景(面板.颜色)
.transition(.不对称(插入:context.insertion,删除:context.remove))
}
}
}
}
}
枚举面板:Int、可大小写、可识别{
案例一=1
案例二=2
案例三=3
var标签:一些视图{
切换自身{
案例一:
返回标签(“标签一”,系统图像:“1.圆圈”)
案例二:
返回标签(“标签二”,系统图像:“2.正方形”)
案例三:
返回标签(“标签三”,系统图像:“星号圆圈”)
}
}
颜色:颜色{
切换自身{
案例一:返回颜色。红色。不透明度(0.5)
案例二:返回颜色。绿色。不透明度(0.5)
案例三:返回颜色。蓝色。不透明度(0.5)
}
}
func makeMove(uotherpanel:panels)->AnyTransition{
返回otherPanel.rawValue
您能分享所需结果的图片吗?我相信这是可能的。请提供一些代码。在开始编写代码之前,我一直在考虑这个问题,所以很遗憾,我没有任何代码,图片也可能无法很好地描述所需的动画,只需想象分段控件选择器,每个分段负责在下面显示其专用视图。视图动画(从左/右滑入/滑出)应匹配拾取器(我们都从苹果公司知道的标准分段控制拾取器)中白色背景条的移动,这表明了当前的选择。我添加了一个草图,描述了一个特定示例案例的预期行为,应该能够很好地解释预期结果和总体问题。我不知道该如何工作,因为除最右边或最左边的视图外,每个视图都必须根据新选择是在其右边还是在其左边从左边和左边滑入。@lenny添加了逻辑以使这些转换成为动态的。请尝试更新的代码。这完全成功了!感谢您提供的详细示例,我实际上能够将其分解为一个自定义绑定和两个状态变量,用于in/out转换。非常欢迎您!这张照片很有帮助。