Last active
February 25, 2020 13:24
-
-
Save zrzka/8352c94e2906be4768d9d386d524fec4 to your computer and use it in GitHub Desktop.
SwiftUI - NavigationView - Deep Link
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
import Combine | |
import SwiftUI | |
extension EnvironmentValues { | |
var deepLink: DeepLink { | |
get { | |
self[DeepLink.self] | |
} | |
set { | |
self[DeepLink.self] = newValue | |
} | |
} | |
} | |
struct DeepLink: EnvironmentKey { | |
let showB = CurrentValueSubject<Bool, Never>(false) | |
let showC = CurrentValueSubject<Bool, Never>(false) | |
static let defaultValue = DeepLink() | |
func presentB() { | |
showB.send(true) | |
} | |
func presentBC() { | |
showB.send(true) | |
showC.send(true) | |
} | |
func presentC() { | |
showC.send(true) | |
} | |
} | |
struct Lazy<Content: View>: View { | |
private let builder: () -> Content | |
init(_ builder: @escaping () -> Content) { | |
self.builder = builder | |
} | |
var body: Content { | |
builder() | |
} | |
} | |
struct A: View { | |
@Environment(\.deepLink) var deepLink | |
@State var isBActive: Bool = false | |
var body: some View { | |
NavigationView { | |
VStack { | |
Spacer() | |
Button(action: { self.deepLink.presentB() }) { | |
Text("Go to B") | |
} | |
Spacer() | |
// | |
// iOS < 13.4 -> presents B, presents C and pops C immediately | |
// iOS = 13.4 -> works as expected, presents B, presents C | |
// | |
Button(action: { self.deepLink.presentBC() }) { | |
Text("Go to B & C") | |
} | |
Spacer() | |
NavigationLink(destination: Lazy { B() }, isActive: $isBActive) { | |
EmptyView().hidden() | |
} | |
.onReceive(deepLink.showB) { show in | |
print("A received showB(\(show))") | |
self.isBActive = show | |
} | |
} | |
.navigationBarTitle("A") | |
} | |
} | |
} | |
struct B: View { | |
@Environment(\.deepLink) var deepLink | |
@State var isCActive: Bool = false { | |
willSet { | |
print("willSet(isCActive): \(isCActive) -> \(newValue)") | |
} | |
didSet { | |
print("didSet(isCActive): \(isCActive)") | |
} | |
} | |
var body: some View { | |
VStack { | |
Button(action: { self.deepLink.presentC() }) { | |
Text("Go to C") | |
} | |
NavigationLink(destination: Lazy { C() }, isActive: $isCActive) { | |
EmptyView().hidden() | |
} | |
.onReceive(deepLink.showC) { show in | |
print("B received showC(\(show))") | |
self.isCActive = show | |
} | |
} | |
.navigationBarTitle("B") | |
} | |
} | |
struct C: View { | |
var body: some View { | |
VStack { | |
Text("Stay, please, stay and don't pop!") | |
} | |
.navigationBarTitle("C") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment