使用状态机状态作为TabView选择

问题描述 投票:0回答:1

尝试实现状态机:

struct Transition {
    var targetState: any ContextState
    var effect: Effect? = nil
    
    typealias Effect = ( Context ) -> ()
}

/// Events may trigger transitions between the states.
/// Each method takes an instance of the 'Context' type as parameter
/// to be able to call methods on the 'Context' to effect actions as required
protocol Events {
    mutating func gotoState1(_: Context) -> Transition?
    mutating func gotoStateě(_: Context) -> Transition?
}

/// Protocol extension to provide DEFAULT implementations of all the Events protocol methods
extension Events {
    mutating func gotoState1(_: Context) -> Transition? { return nil }
    mutating func gotoState2(_: Context) -> Transition? { return nil }
}

/// Activities related to the states themselves.
/// These methods will allow each concrete state type to define 'entry' and 'exit' activities
/// for the state it represents
protocol Activities {
    func enter( _ : Context )
    func exit( _ : Context )
}

/// With DEFAULT empty implementation of both the methods in place, concrete state types will
/// need to implement these methods only for states that actually have 'entry' and/or 'exit'
/// activities respectively
extension Activities {
    func enter( _ : Context ) {}
    func exit( _ : Context ) {}
}

typealias ContextState = Events & Activities

具体状态实现为:

struct State1: ContextState {
    func enter( _ : GoProRemote ) {
        // TODO: Perform the action to be taken once the state is entered
    }
    
    /// Go to State2
    mutating func gotoState2(_: Context) -> Transition? {
        return Transition(targetState: State2())
    }
}

struct State2: ContextState {
    func enter( _ : GoProRemote ) {
        // TODO: Perform the action to be taken once the state is entered
    }
    
    /// Go to State1
    mutating func gotoState1(_: Context) -> Transition? {
        return Transition(targetState: State1())
    }
}

最后是控制器:

struct Context {

    @State var state: ContextState = State1()
    
    /// Perform transition to the new state
    private func perform( transition : Transition? ) {
        guard let transition = transition else { return }
        state.exit( self )
        transition.effect?( self )
        state = transition.targetState
        state.enter( self )
    }
}

在 SwiftUI 中,有一个包含 TabView 的视图,它是特定状态的图形表示。其中的每个选项卡都是针对一种状态设计的。

struct SMView: View {

    var context: Context

    var body: some View {
        TabView(selection: $context.state) {
            Text("State 1").tag(State1())
            Text("State 2").tag(State2())
        }
        .onChange(of: $context.state, {
                print("Going to \($context.state) state")
        })
    }
}

这就是问题所在。上面的代码不起作用,因为它在状态变量的可哈希不一致性等中生成错误......

有人知道如何使用状态结构为 TabView 中的选项卡建立索引吗?

swift swiftui state-machine
1个回答
0
投票
@State var context = Context()

同时从 Context 结构体中删除

@State

结构体内部的函数需要标记为变异,例如

mutating func perform(...

供动画参考,它是

withAnimation {
   context.selection = 
}
© www.soinside.com 2019 - 2024. All rights reserved.