Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Source/Turbo/Navigator/Helpers/PathIdentifiable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import UIKit

/// A view controller may conform to `PathIdentifiable` to expose the URL it represents.
///
/// `Navigator` uses this URL — instead of view-controller type equality — when deciding
/// whether a proposed visit refers to the page already on top of the stack or to the page
/// directly beneath it. Without this conformance, two instances of the same custom view
/// controller class but with different URLs are indistinguishable to the navigator and may
/// be incorrectly popped or replaced.
///
/// `Visitable` inherits from this protocol, so existing visitable view controllers satisfy
/// it automatically via `initialVisitableURL`.
public protocol PathIdentifiable: AnyObject {
var initialVisitableURL: URL { get }
}
8 changes: 4 additions & 4 deletions Source/Turbo/Navigator/NavigationHierarchyController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ class NavigationHierarchyController {
private func visitingSamePage(on navigationController: UINavigationController,
with controller: UIViewController,
via proposal: VisitProposal) -> Bool {
if let visitable = navigationController.topViewController as? Visitable {
return visitable.initialVisitableURL.isSameLocation(as: proposal.url, pathProperties: proposal.properties)
if let pathIdentifiable = navigationController.topViewController as? PathIdentifiable {
return pathIdentifiable.initialVisitableURL.isSameLocation(as: proposal.url, pathProperties: proposal.properties)
} else if let topViewController = navigationController.topViewController {
return topViewController.isMember(of: type(of: controller))
}
Expand All @@ -162,8 +162,8 @@ class NavigationHierarchyController {
guard navigationController.viewControllers.count >= 2 else { return false }

let previousController = navigationController.viewControllers[navigationController.viewControllers.count - 2]
if let previousVisitable = previousController as? VisitableViewController {
return previousVisitable.initialVisitableURL.isSameLocation(as: proposal.url, pathProperties: proposal.properties)
if let pathIdentifiable = previousController as? PathIdentifiable {
return pathIdentifiable.initialVisitableURL.isSameLocation(as: proposal.url, pathProperties: proposal.properties)
}
return type(of: previousController) == type(of: controller)
}
Expand Down
3 changes: 1 addition & 2 deletions Source/Turbo/Visitable/Visitable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ public protocol VisitableDelegate: AnyObject {
func visitableDidRequestRefresh(_ visitable: Visitable)
}

public protocol Visitable: AnyObject {
public protocol Visitable: AnyObject, PathIdentifiable {
var visitableViewController: UIViewController { get }
var visitableDelegate: VisitableDelegate? { get set }
var visitableView: VisitableView { get }
var initialVisitableURL: URL { get }
var currentVisitableURL: URL { get }

func visitableDidRender()
Expand Down
Loading