Created
January 6, 2022 13:56
-
-
Save Higher08/bad799a00bb83a31fe6e824821e860d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Router.swift | |
// Routing | |
// | |
// | |
import SwiftUI | |
enum Views: CaseIterable { | |
case main | |
case moviePageView | |
case serialPageView | |
case search | |
case favorite | |
case movieDetail | |
case serialDetail | |
} | |
enum Params { | |
case noData | |
case detailData(id: Int) | |
} | |
final class ViewRouter: ObservableObject { | |
@Published var currentView: Views = .main | |
@Published var views: [Views: AnyView] = [:] | |
@Published var id: Int = 0 | |
private var history = LimitedArray<(Views, Params)>(maxSize: 10) | |
let animation: Animation = .spring() | |
init() { | |
views[.main] = AnyView(MainView()) | |
views[.movieDetail] = AnyView(DetailFilmView()) | |
views[.search] = AnyView(SearchTextView()) | |
views[.serialPageView] = AnyView(SerialsPage()) | |
views[.serialDetail] = AnyView(DetailTVView()) | |
} | |
func setView(_ view: Views, params: Params = .noData) { | |
currentView = view | |
history.insert((view, params), at: 0) | |
print(history) | |
switch params { | |
case .detailData(let id): | |
print(id) | |
self.id = id | |
default: | |
break | |
} | |
} | |
func returnToLatest() { | |
print(history) | |
guard history.count > 1 else { | |
return | |
} | |
let lastItem = history[1] | |
switch lastItem.1 { | |
case .detailData(let id): | |
print(id, self.id) | |
if id == self.id { return } | |
self.id = id | |
default: | |
break | |
} | |
withAnimation { | |
currentView = lastItem.0 | |
} | |
history.remove(at: 0) | |
} | |
} | |
/// an array-like struct that has a fixed maximum capacity | |
/// any element over the maximum allowed size gets discarded | |
struct LimitedArray<T> { | |
private(set) var storage: [T] = [] | |
public let maxSize: Int | |
/// creates an empty array | |
public init(maxSize: Int) { | |
self.maxSize = maxSize | |
} | |
/// takes the max N elements from the given collection | |
public init<S: Sequence>(from other: S, maxSize: Int) where S.Element == T { | |
self.maxSize = maxSize | |
storage = Array(other.prefix(maxSize)) | |
} | |
/// adds a new item to the array, does nothing if the array has reached its maximum capacity | |
/// returns a bool indicated the operation success | |
@discardableResult public mutating func append(_ item: T) -> Bool { | |
if storage.count < maxSize { | |
storage.append(item) | |
return true | |
} else { | |
return false | |
} | |
} | |
/// inserts an item at the specified position. if this would result in | |
/// the array exceeding its maxSize, the extra element are dropped | |
public mutating func insert(_ item: T, at index: Int) { | |
storage.insert(item, at: index) | |
if storage.count > maxSize { | |
storage.remove(at: maxSize) | |
} | |
} | |
public mutating func remove(at index: Int) { | |
storage.remove(at: index) | |
} | |
// add here other methods you might need | |
} | |
// let's benefit all the awesome operations like map, flatMap, reduce, filter, etc | |
extension LimitedArray: MutableCollection { | |
public var startIndex: Int { return storage.startIndex } | |
public var endIndex: Int { return storage.endIndex } | |
public subscript(_ index: Int) -> T { | |
get { return storage[index] } | |
set { storage[index] = newValue } | |
} | |
public func index(after i: Int) -> Int { | |
return storage.index(after: i) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment