【问题标题】:Handling multiple states in swift快速处理多个状态
【发布时间】:2019-09-07 23:12:14
【问题描述】:

我有一个需要处理 9 种不同状态的表格视图。 我有两个部分包含不同的数据模型(A,B) 这两部分逻辑上相互依赖

1) !A.isEmpty
2) !B.isEmpty
3) A show expandable footer (A.count > 5)
4) B show expandable footer (B.count > 5)
5) A shows collapsable footer (user clicked on A.expandable footer)
6) B shows collapsable footer (user clicked on B.expandable footer
7) A.count > 3 && B.isEmpty
8) B.count > 3 && A.isEmpty
9) A.count > 3 && B.isEmpty && A shows collapsable footer (user clicked on A.expandable footer)

是否有处理多个状态的标准?我正在考虑创建某种状态结构。处理这个问题的“行业标准”是什么?

这是我目前使用的——许多计算变量

let numberOfCells = 5
var A.expanded = false
var B.expanded = false
var A = [Data]()
var B = [Data]()
var state5 = A.expanded
var state6 = B.expanded

var A.showFooter: Bool {
    return A.count > numberOfCells
}
var B.showFooter: Bool {
    return B.count > numberOfCells
}
var state7: Bool {
    return A.showFooter && B.isEmpty
}
var state8: Bool {
    return A.isEmpty && B.showFooter
}
var state9: Bool {
    return (state7 && state6)
        || (state8 && state5)
}

【问题讨论】:

  • 您看过位掩码吗?您可以有一个 9 位的变量来存储所有内容,然后您可以分别检查每个位。有很多教程可以帮助您入门
  • @Russell 这实际上是一个非常好的主意!谢谢,我想我会尝试实现这一点。
  • 您在gameplaykit中有一个免费的状态机,它将为您节省很多工作。
  • @E.Coms 有趣.. 虽然这对我的问题来说可能有点矫枉过正。

标签: ios swift architecture state


【解决方案1】:

我认为枚举或结构会满足您的需求。

struct Video {
enum State {
    case willDownload(from: URL)
    case downloading(task: Task)
    case playing(file: File, progress: Double)
    case paused(file: File, progress: Double)
}

var state: State

}

    private func resolveActionButtonImage() -> UIImage {
    // The image for the action button is declaratively resolved
    // directly from the video state
    switch video.state {
        // We can easily discard associated values that we don't need
        // by simply omitting them
        case .willDownload:
            return .wait
        case .downloading:
            return .cancel
        case .playing:
            return .pause
        case .paused:  
            return .play
    } 
}

}

参考: https://www.swiftbysundell.com/posts/modelling-state-in-swift

【讨论】:

  • 如何处理多个状态?例如,我的视频将有 willDownload 并暂停。而resolveActionButtonImage 需要处理这两种情况。
  • 如果两个数据模型相互关联,我相信解决方案可能是简化您的数据模型并将它们组合在一起。但是,如果模型通常是独立的,但您只需要一个视图控制器的逻辑,请创建一个类对象,该对象接受两个模型并解析您需要的信息,以避免使您的视图控制器臃肿。
【解决方案2】:

我决定使用一个对象来保存逻辑和位掩码来充当状态。

private struct StateModel: OptionSet {
    let rawValue: Int

    static let AIsEmpty = StateModel(rawValue: 1 << 0)
    static let AHasValues = StateModel(rawValue: 1 << 1)
    static let BIsEmpty = StateModel(rawValue: 1 << 2)
    static let BHasValues = StateModel(rawValue: 1 << 3)
    static let AFooterIsVisible = StateModel(rawValue: 1 << 4)
    static let BIsVisible = StateModel(rawValue: 1 << 5)
    static let AFooterIsExpanded = StateModel(rawValue: 1 << 6)
    static let BFooterIsExpanded = StateModel(rawValue: 1 << 7)
    static let AFooterShowsCTA: StateModel = [.AHasValues, .BIsEmpty]
    static let BFooterShowCTA: StateModel = [.AIsEmpty, .BHasValues]
    static let ACTAAsCell: StateModel = [.AFooterShowsCTA, .AFooterIsVisible]
    static let BCTAAsCell: StateModel = [.BFooterShowCTA, .BFooterIsExpanded]
}

class Logic {

var stateModel: StateModel = []

//Should AFooter show CTA?
var showAFooter: Bool {
  stateModel.contains(.AFooterShowsCTA)
}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 2020-11-17
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多