I'm trying to build an app that has a NavigationSplitView and a NavigationStack in the detail View.
The normal flow works fine, but if I navigate to the second page on the detail view and then select another menu item (i.e. the second item), I'm still on the detail page of the first menu item.
The underlying view of the second detail view changes. This can be observed by the change of the back button label.
How do I ensure that my NavigationStack is also reset when I change the selection?
import SwiftUI
enum Option: String, Equatable, Identifiable {
case first
case second
var id: Option { self }
}
struct ContentView: View {
@State private var selection: Option?
var body: some View {
NavigationSplitView {
List(selection: $selection) {
NavigationLink(value: Option.first) {
Text("First")
}
NavigationLink(value: Option.second) {
Text("Second")
}
}
} detail: {
switch selection {
case .none:
Text("Please select one option")
case .some(let wrapped):
NavigationStack {
DetailView(title: wrapped.rawValue)
}
}
}
.navigationSplitViewStyle(.balanced)
}
}
struct DetailView: View {
private var title: String
init(title: String) {
self.title = title
}
var body: some View {
List {
NavigationLink {
Text(title)
} label: {
Text("Show \(title) detail")
}
}
.navigationTitle(title)
}
}
Post
Replies
Boosts
Views
Activity
If I place a LazyVGrid inside a ScrollView with other views inside another ScrollView. The pinnedViews option of the LazyVGrid stops working. The section header scrolls out of the viewport like it's not pinned.
The complete view should scroll horizontally without another horizontal scrolling on the grid. The grid itself is wider than than the device width so it should scroll horizontally. The problem is now that the pinnedViews option of the LazyVGrid is not working.
If I remove the inner ScrollView and set the scroll mode of the outer to [.vertical, .horizontal] the pinned header works, except that now the view above and below the grid are also the same width of the LazyVGrid, which is not wat I want.
Is it possible to pin the section header to the outer ScrollView and not to the direct parent ScrollView of the LazyVGrid?
struct ContentView: View {
var body: some View {
ScrollView(.vertical) {
Text("Other content")
.frame(maxWidth: .infinity, minHeight: 100)
.background(Color.yellow)
ScrollView(.horizontal) {
LazyVGrid(
columns: Array(repeating: GridItem(.fixed(200), spacing: 0, alignment: .center), count: 9),
spacing: 16,
pinnedViews: [.sectionHeaders]
) {
Section(header: header) {
ForEach(1..<500) {
Text("Cell #\($0)")
}
}
}
}
Text("Other content")
.frame(maxWidth: .infinity, minHeight: 100)
.background(Color.yellow)
}
}
var header: some View {
LazyVGrid(
columns: Array(repeating: GridItem(.fixed(200), spacing: 0, alignment: .center), count: 9),
spacing: 16
) {
ForEach(1..<10) {
Text("Header \($0)")
}
}
.padding(.vertical)
.background(Color.blue)
.foregroundColor(.white)
}
}
The example is complete so you can test it easily. It works as expected, except that the pinned section header is not working.
I am currently programming an app that should work offline. The data should be synchronized periodically in the background. Most of the data only needs to be loaded from the server. A few also need to be sent to the server.
My first thought for synchronization was to use the BackgroundTask framework. So to use several BGAppRefreshTaskRequest for the synchronization. Several, because the data is refreshed with different frequency.
Since the normal background URLSession does not work when the request is started via a Background Task the request has to be executed via a Background URLSession. Is this correct? I've found different information about this, so sometimes it's said that normal requests without a background session also work.
The main problem with the application is that the user authenticates via OAuth and the token is only valid for one hour. After that, the token has to be renewed. Is this possible with the Background URLSession? My idea now was to check for a 401 error on the DownloadTask and then initialize a token refresh, once successful retry the original request. This would all run through the Background URLSession. However, since the system schedules and executes the requests I wonder if this would even work in this constellation.
Maybe there are other ways to implement synchronization. What would be the best approach here?
Thanks,
Lars