A lot of apps (for example the Apple Music app) move some text only to the NavigationTitle once a user scrolls past it. Is there a way to do this in SwiftUI (preferably without using GeometryReader or ScrollviewReader)?
So the simplest way to achieve this is to use onAppear
and onDisappear
for the content you want to be a title. I.e. something like this:
struct SomeView: View {
@State var songTitle = "Whenever You Need Somebody" // Probably comes form some data model
@State var screenTitle = "" // <-- what to show in screen title, nothing by default
var body: some View {
ScrollView { // Just taking this combo as example, could be a list, or a form, or anything else with scroll
LazyVStack {
// ... some elements
Text(songTitle)
.onAppear {
screenTitle = "" // <-- hides title when this text is visible
}
.onDisappear {
screenTitle = songTitle // <-- shows title when this text is not visible
}
// ... some elements
}
}
}
}
This basic solution will work well on some layouts, but may require some fine tuning on others. This is because SwiftUI's onAppear
and onDisappear
are not at exactly the moment when view is shown or hidden, it's rather done a few lines ahead of time (for onAppear
), and a few lines after for onDisappear
. So in some layouts you may need to have these events for some elements that come before and after the text you want to use for a title. Or you may implement a more sophisticated solution using GeometryReader
(example)