我正在编写一个在SwiftUI中模仿macOS侧边栏行为的检查器视图。它只在整个视图出现和消失时使用.transition(.move(edge: .trailing))
,但在内部视图之间切换时不使用。
所以我想出了以下代码。Selection
是一个枚举表示视图一对一,总是以case none
开始。inspect()
方法用于改变选择值和确定是否使用动画(记得我提到过不要使用动画时,切换内部视图)。我附上我的完整代码在最后。
但是,永远不会有任何动画应用.我该如何解决这个问题?
如果我在inspect()
方法中直接使用@State selection
这个更具体的方法,动画会回来,但是如果我有另一个Inspector,比如@State var selection2: Selection2
,就不能重用代码。
func inspect(to target: Selection) {
if target.rawValue == 0 {
withAnimation {
selection = target
}
} else {
if selection.rawValue == 0 {
withAnimation {
selection = target
}
} else {
selection = target
}
}
}
下面是我的完整代码:
struct ContentView: View {
enum Selection: Int {
case none
case view1
case view2
case view3
}
@State var selection: Selection = .none
func inspect<Selection: RawRepresentable<Int>>(_ selection: inout Selection, to target: Selection) {
if target.rawValue == 0 {
withAnimation {
selection = target
}
} else {
if selection.rawValue == 0 {
withAnimation {
selection = target
}
} else {
selection = target
}
}
}
var body: some View {
HStack {
VStack {
Button("None") {
inspect(&selection, to: .none)
}
Button("View 1") {
inspect(&selection, to: .view1)
}
Button("View 2") {
inspect(&selection, to: .view2)
}
Button("View 3") {
inspect(&selection, to: .view3)
}
}
Group {
if selection.rawValue == 1 {
Text("Hello 1")
} else if selection.rawValue == 2 {
Text("Hello 2")
} else if selection.rawValue == 3 {
Text("Hello 3")
}
}
.transition(.move(edge: .trailing))
}
}
}
1条答案
按热度按时间n6lpvg4x1#
你的代码看起来有点复杂,所以我已经简化了它,如果我理解你想做什么正确的行为也如预期。
首先,我直接在
inspect
函数中使用了@State属性,因此不需要将其作为参数传递,而且这里也不需要泛型正如上面所看到的,我直接使用枚举大小写,而不是任何原始值,事实上,我从枚举中删除了原始值
并因此更改
Group
中的代码总的来说,我认为这使得代码更干净,更容易阅读。