-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
199 additions
and
154 deletions.
There are no files selected for viewing
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
|
||
@_exported import SwiftUI |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
|
||
public class RouteRequest: ObservableObject { | ||
public enum RouterType { | ||
case push | ||
case present | ||
} | ||
/// 路由操作 | ||
public var routeAction: Router.RouteAction = .empty | ||
public let url: URL? | ||
/// 参数 | ||
public var param: Any? | ||
public var options = [String: Any]() | ||
public var routeType = RouterType.push | ||
public required init(url: URL) { | ||
self.url = url | ||
self.isHandle = false | ||
} | ||
public required init(action: Router.RouteAction, url: URL? = nil) { | ||
self.url = url | ||
self.routeAction = action | ||
self.isHandle = true | ||
} | ||
/// 是否需要经过router handler | ||
internal var isHandle: Bool = false | ||
} | ||
|
||
|
||
public extension RouteRequest { | ||
/// 跳转到指定页面 | ||
convenience init(page: Router.RoutePath, url: URL? = nil){ | ||
self.init(action: .page(page), url: url) | ||
} | ||
var routePath: Router.RoutePath { | ||
switch routeAction { | ||
case .page(let path): | ||
return path | ||
default: | ||
return .page404 | ||
} | ||
} | ||
} | ||
public extension Router.RoutePath { | ||
var request: RouteRequest { | ||
return RouteRequest(page: self) | ||
} | ||
} | ||
extension RouteRequest: Hashable { | ||
public static func == (lhs: RouteRequest, rhs: RouteRequest) -> Bool { | ||
return lhs.routeAction == rhs.routeAction && lhs.url == rhs.url | ||
} | ||
public func hash(into hasher: inout Hasher) { | ||
hasher.combine(routePath) | ||
hasher.combine(routeAction) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
extension Router { | ||
fileprivate func handlePage(_ request: RouteRequest) { | ||
if(request.routePath == .root) { | ||
popToRoot() | ||
self.rootPath = request | ||
return | ||
} | ||
switch request.routeType { | ||
case .push: | ||
pagePath.append(request) | ||
case .present: | ||
presentingSheet = request | ||
} | ||
} | ||
fileprivate func handleAction(_ request: RouteRequest) { | ||
guard let builder = self.actionBuilderMap[request.routePath] else { | ||
return | ||
} | ||
builder(request) | ||
} | ||
} | ||
public extension Router { | ||
func go(_ request: RouteRequest) { | ||
if !request.isHandle { | ||
request.routeAction = handler(request) | ||
request.isHandle = true | ||
} | ||
switch request.routeAction { | ||
case .empty: break | ||
case .page: | ||
handlePage(request) | ||
case .action: | ||
handleAction(request) | ||
} | ||
|
||
} | ||
func pop() { | ||
if presentingSheet != nil { | ||
presentingSheet = nil | ||
} else if !pagePath.isEmpty { | ||
pagePath.removeLast() | ||
} | ||
} | ||
func popToRoot() { | ||
if presentingSheet != nil { | ||
presentingSheet = nil | ||
} | ||
pagePath.removeAll() | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
public class Router: ObservableObject { | ||
public enum RouteAction: Equatable, Hashable { | ||
case empty | ||
case page(Router.RoutePath) | ||
case action(Router.RoutePath) | ||
} | ||
|
||
public struct RoutePath: RawRepresentable, Equatable, Hashable { | ||
public static let page404 = RoutePath(rawValue: "page/404") | ||
public static let root = RoutePath(rawValue: "page/root") | ||
public let rawValue: String | ||
public init(rawValue: String) { | ||
self.rawValue = rawValue | ||
} | ||
} | ||
|
||
typealias PageBuilder = (RouteRequest) -> any View | ||
typealias ActionBuilder = (RouteRequest) -> Void | ||
public static let shared = Router() | ||
|
||
public var handler:(RouteRequest) -> RouteAction = { _ in | ||
return .empty | ||
} | ||
|
||
public var page404: (RouteRequest) -> any View = { _ in | ||
return EmptyView() | ||
} | ||
@Published | ||
public var rootPath = RoutePath.root.request | ||
|
||
@Published | ||
public var pagePath = [RouteRequest]() | ||
@Published | ||
public var presentingSheet: RouteRequest? | ||
|
||
internal var pageBuilderMap = [RoutePath: PageBuilder]() | ||
internal var actionBuilderMap = [RoutePath: ActionBuilder]() | ||
public init() {} | ||
|
||
var sheetBind: Binding<Bool> { | ||
return .init { | ||
return self.presentingSheet != nil | ||
} set: { _ in | ||
self.presentingSheet = nil | ||
} | ||
|
||
} | ||
} | ||
|
||
public extension Router { | ||
func addPage(_ path: RoutePath, | ||
@ViewBuilder | ||
builder: @escaping (RouteRequest) -> some View) { | ||
pageBuilderMap[path] = builder | ||
} | ||
func addAction(_ path: RoutePath, | ||
@ViewBuilder | ||
builder: @escaping (RouteRequest) -> Void) { | ||
actionBuilderMap[path] = builder | ||
} | ||
func page(_ request: RouteRequest) -> AnyView { | ||
if(!request.isHandle) { | ||
request.routeAction = handler(request) | ||
request.isHandle = true | ||
} | ||
let pid = request.routePath | ||
guard let builder = pageBuilderMap[pid] else { | ||
return AnyView(page404(request)) | ||
} | ||
return AnyView(builder(request)) | ||
} | ||
} | ||
|
||
|
||
extension Router { | ||
|
||
} | ||
|
||
extension EnvironmentValues { | ||
var pageRouter: Router { | ||
return serviceValues[RouteService.self] | ||
} | ||
} |