[英]SwiftUI View Transition matching to an Segmented Picker
Is it possible to have three (more than 2!) views that are animated in and out from the sides according to an Picker
with the SegmentedPickerStyle()
style?根据具有
SegmentedPickerStyle()
样式的Picker
,是否可以拥有三个(超过 2 个!)从侧面进出动画的视图?
Having only 2 items in the picker makes the job static and thus a .transition(.move(edge: .leading))
on the first and a .transition(.move(edge: .trailing))
on the last view is sufficient.选择器中只有 2 个项目使得工作 static 和因此第一个视图上的
.transition(.move(edge: .leading))
.transition(.move(edge: .trailing))
和最后一个视图上的 .transition(.move(edge: .trailing)) 就足够了。 But what about more than 2?但是超过2个呢?
Maybe there is a way to make the edge: ...
parameter of the transition dynamically set to .leading
or .trailing
and depending on whether how the new value of the binding is greater or less than the current on.也许有一种方法可以使
edge: ...
转换的参数动态设置为.leading
或.trailing
并且取决于绑定的新值是大于还是小于当前值。
I created the following sketch to demonstrate the issue of having the same view (view 2) with a different transition depending on whether a view on its right or left is selected.我创建了下面的草图来演示具有不同转换的相同视图(视图 2)的问题,具体取决于选择其右侧或左侧的视图。 Please see this only as an example, the problem is not restricted to only three segments, nor only the middle view, nor only disappearing transitions etc..
请仅将其视为示例,问题不仅限于三个段,也不仅限于中间视图,也不仅限于消失的过渡等。
Update The secret sauce is to make sure the transition fires with an animation and tell it what direction to go before doing so.更新秘诀是确保使用 animation 触发转换,并在这样做之前告诉它 go 的方向。 Give this a try:
试试这个:
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())
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.