Skip to content

Commit

Permalink
Update readme and clean code (#44)
Browse files Browse the repository at this point in the history
* Improves TabBarCoordinator and clean code (#39)
  • Loading branch information
felilo authored Dec 18, 2024
1 parent 3ee3588 commit 873d849
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import SwiftUI
import SUICoordinator

struct CustomTabbarView<DataSource: TabbarCoordinatorType>: View where DataSource.Page: TabbarPage{
struct CustomTabbarView<DataSource: TabbarCoordinatorType>: View {

// ---------------------------------------------------------------------
// MARK: Typealias
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,28 @@ class ActionListViewModel: ObservableObject {
self.coordinator = coordinator
}

func navigateToPushView() async {
@MainActor func navigateToFirstView() async {
await coordinator.navigateToPushView()
}

func presentSheet() async {
@MainActor func presentSheet() async {
await coordinator.presentSheet()
}

func presentFullscreen() async {
@MainActor func presentFullscreen() async {
await coordinator.presentFullscreen()
}

func presentDetents() async {
@MainActor func presentDetents() async {
await coordinator.presentDetents()
}

func presentTabbarCoordinator() async {
@MainActor func presentTabbarCoordinator() async {
await coordinator.presentTabbarCoordinator()
}

func finsh() async {
await coordinator.finsh()
@MainActor func finish() async {
await coordinator.finish()
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ extension CoordinatorType {
/// - withDismiss: A boolean value indicating whether to dismiss the coordinator.
/// - Returns: An asynchronous void task representing the finish process.
func finish(animated: Bool = true, withDismiss: Bool = true) async -> Void {
guard !isEmptyCoordinator else { return }

guard let parent, withDismiss else {
return await emptyCoordinator(animated: animated)
}
Expand All @@ -164,11 +166,16 @@ extension CoordinatorType {
}

/// Cleans up the coordinator.
func swipedAway() {
guard !isEmptyCoordinator else { return }
func swipedAway(coordinator: TCoordinatorType) {
let sheetCoordinator = router.sheetCoordinator

Task(priority: .low) { [weak self] in
await self?.finish(animated: false, withDismiss: false)
sheetCoordinator.onRemoveItem = { [weak coordinator] id in
if let uuid = coordinator?.uuid, id.contains(uuid) {
Task(priority: .utility) { [weak coordinator] in
await coordinator?.finish(animated: false, withDismiss: false)
sheetCoordinator.onRemoveItem = nil
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ public extension CoordinatorType {
let item = SheetItem(
id: "\(coordinator.uuid) - \(presentationStyle.id)",
animated: animated,
presentationStyle: (presentationStyle != .push) ? presentationStyle : .sheet,
view: { [weak coordinator] in coordinator?.getView() },
onFinish: {[weak coordinator] in coordinator?.swipedAway()}
presentationStyle: (presentationStyle != .push) ? presentationStyle : .sheet,
view: { [weak coordinator] in coordinator?.getView() }
)

swipedAway(coordinator: coordinator)
router.presentSheet(item: item)
}

Expand Down
8 changes: 1 addition & 7 deletions Sources/SUICoordinator/Router/DefaultRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ public struct DefaultRoute: RouteType {

/// The view to be presented for the route.
public var view: any View {
var view = AnyView(EmptyView()).id(UUID().uuidString)

if let v = content() {
view = AnyView(v).id(String(describing: v.self))
}

return view
getView(from: content)
}
}
13 changes: 13 additions & 0 deletions Sources/SUICoordinator/Router/RouteType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,16 @@ public protocol RouteType: SCHashable {
/// The body of the route, conforming to the View protocol.
@ViewBuilder @MainActor var view: Body { get }
}

extension RouteType {

func getView(from content: () -> (Body?)) -> any View {
var view = AnyView(EmptyView()).id(UUID().uuidString)

if let v = content() {
view = AnyView(v).id(String(describing: v.self))
}

return view
}
}
12 changes: 12 additions & 0 deletions Sources/SUICoordinator/SheetCoordinator/SheetCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ final public class SheetCoordinator<T>: ObservableObject {
/// The presentation style of the last presented sheet.
public private(set) var animated: Bool?

private var backUpItems: [Int: String] = [:]

var onRemoveItem: ((String) -> Void)?

// ---------------------------------------------------------
// MARK: Constructor
// ---------------------------------------------------------
Expand Down Expand Up @@ -87,6 +91,7 @@ final public class SheetCoordinator<T>: ObservableObject {
animated = sheet.animated
lastPresentationStyle = sheet.presentationStyle
items.append(sheet)
backUpItems[totalItems - 1] = sheet.id
}

/// Removes the last presented sheet.
Expand All @@ -106,6 +111,12 @@ final public class SheetCoordinator<T>: ObservableObject {
/// - index: The index of the item to remove.
@MainActor func remove(at index: Int) {
guard isValidIndex(index) else { return }

if let id = backUpItems[index] {
onRemoveItem?(id)
backUpItems.removeValue(forKey: index)
}

items.remove(at: index)
}

Expand All @@ -117,6 +128,7 @@ final public class SheetCoordinator<T>: ObservableObject {
await makeNilItem(at: 0)
lastPresentationStyle = nil
items.removeAll()
backUpItems.removeAll()
}

// ---------------------------------------------------------
Expand Down
30 changes: 1 addition & 29 deletions Sources/SUICoordinator/SheetCoordinator/SheetItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ public struct SheetItem<T>:SCHashable, SheetItemType {
/// The transition presentation style for presenting the sheet item.
let presentationStyle: TransitionPresentationStyle

private var itemDeallocate: SheetItemDeallocator?

// ---------------------------------------------------------
// MARK: Constructor
// ---------------------------------------------------------
Expand All @@ -62,15 +60,12 @@ public struct SheetItem<T>:SCHashable, SheetItemType {
id: String,
animated: Bool,
presentationStyle: TransitionPresentationStyle,
view: @escaping () -> T?,
onFinish: (() -> Void)? = nil
view: @escaping () -> T?
) {
self.view = view
self.animated = animated
self.presentationStyle = presentationStyle
self.id = id

itemDeallocate = .init(onFinish: onFinish)
}

// ---------------------------------------------------------
Expand All @@ -86,26 +81,3 @@ public struct SheetItem<T>:SCHashable, SheetItemType {
animated
}
}


/// A utility class to handle deallocation of sheet items, providing a callback
/// that is executed upon deinitialization of the object.
class SheetItemDeallocator {

/// A closure that is invoked when the instance is deallocated.
var onFinish: (() -> Void)?

/// Initializes a new `SheetItemDeallocator` instance.
///
/// - Parameter onFinish: A closure to be executed when the instance is deallocated. Defaults to `nil`.
init(onFinish: (() -> Void)? = nil ) {
self.onFinish = onFinish
}

/// Deinitializes the instance, invoking the `onFinish` closure if set, and
/// cleans up the closure reference to avoid potential memory leaks.
deinit {
onFinish?()
onFinish = nil
}
}
2 changes: 1 addition & 1 deletion Sources/SUICoordinator/Tabbar/TabbarCoordinatorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import SwiftUI
import Foundation

struct TabbarCoordinatorView<DataSource: TabbarCoordinatorType>: View where DataSource.Page: TabbarPage {
struct TabbarCoordinatorView<DataSource: TabbarCoordinatorType>: View {

typealias Page = DataSource.Page
typealias BadgeItem = DataSource.BadgeItem
Expand Down

0 comments on commit 873d849

Please sign in to comment.