Skip to content

Instantly share code, notes, and snippets.

@chrisfsampaio
Last active November 22, 2019 01:28
Show Gist options
  • Save chrisfsampaio/ed84a14bf683cd7f561c9c77dbb841ac to your computer and use it in GitHub Desktop.
Save chrisfsampaio/ed84a14bf683cd7f561c9c77dbb841ac to your computer and use it in GitHub Desktop.
PreferenceKey SwiftUI
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