Last active
November 22, 2019 01:28
-
-
Save chrisfsampaio/ed84a14bf683cd7f561c9c77dbb841ac to your computer and use it in GitHub Desktop.
PreferenceKey SwiftUI
This file contains hidden or 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 SwiftUI | |
struct ContentView: View { | |
var body: some View { | |
TabView { | |
ListView() | |
.tabItem { | |
Text("First") | |
} | |
Text("hey") | |
.tabItem { | |
Text("Second") | |
} | |
} | |
.overlayPreferenceValue(TitlePreferenceKey.self) { titles in | |
VStack { | |
Text(titles.last ?? "") | |
Spacer() | |
} | |
} | |
} | |
} | |
struct ListView: View { | |
var body: some View { | |
NavigationView { | |
VStack(spacing: 36) { | |
NavigationLink(destination: DetailView()) { | |
Text("Push detail view1") | |
} | |
NavigationLink(destination: DetailView()) { | |
Text("Push detail view2") | |
} | |
NavigationLink(destination: DetailView()) { | |
Text("Push detail view3") | |
} | |
} | |
.testTitle("List View - Title") | |
} | |
} | |
} | |
struct DetailView: View { | |
var body: some View { | |
Text("Detail View") | |
.testTitle("Detail View - Title") | |
} | |
} | |
struct TitlePreferenceKey: PreferenceKey { | |
static var defaultValue: [String] = [] | |
static func reduce(value: inout [String], nextValue: () -> [String]) { | |
let added = nextValue() | |
value.append(contentsOf: added) | |
} | |
} | |
struct TitleModifier: ViewModifier { | |
let title: String | |
@State var currentTitle: String? | |
func body(content: Content) -> some View { | |
return content | |
.transformPreference(TitlePreferenceKey.self) { value in | |
if let title = self.currentTitle { | |
value.append(title) | |
} | |
} | |
.onDisappear { | |
self.currentTitle = nil | |
} | |
.onAppear { | |
self.currentTitle = self.title | |
} | |
// This hack is helping SwiftUI to notice there was a change in the view tree. | |
// There's something weird going on with NavigationView making changes not propagating back to ancestors properly. | |
.background(EmptyView().tag(currentTitle)) | |
} | |
} | |
extension View { | |
func testTitle(_ title: String) -> some View { | |
return modifier(TitleModifier(title: title)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment