I'm trying to setup my view so that there's (in order from top of display to bottom) a VStack with some content, followed by a List, followed by another VStack with a couple buttons where progressive blurs separate the list and the two VStack's content. Now, in the current version of my app when the user scrolls up or down, the list just cuts off. I'm having a very difficult time maintaining the entire view's vertical positioning while adding these blurs with ZStack. The code below is the current implementation with an attempted progressive blur. Right now, it's close, but the list is acting exactly how I don't want it - anchoring to the top of the display (its natural position) and causes the toolbar to blur when scrolled under (I can't disable toolbar without losing my toolbarItems either). Any help is appreciated.
NavigationStack {
VStack {
ZStack {
List(filteredItems) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
HStack(spacing: 15) {
Image(systemName: item.icon)
VStack(alignment: .leading) {
Text(item.name)
Text("")
}
.multilineTextAlignment(.leading)
}
.padding(.vertical, 5)
}
}
.scrollIndicators(.hidden)
.scrollContentBackground(.hidden)
VStack(spacing: 5) {
if #available(iOS 18.0, *) {
Image(systemName: "plus.square.on.square.fill")
.resizable()
.scaledToFit()
.frame(maxHeight: 50)
.symbolEffect(.bounce.up, options: .nonRepeating)
} else {
Image(systemName: "plus.square.on.square.fill")
.resizable()
.scaledToFit()
.frame(maxHeight: 50)
}
Text("Items")
.font(.largeTitle.bold())
Text("Create, View, and Manage Your Items")
.font(.system(size: 12).weight(.bold))
.multilineTextAlignment(.center)
ScrollView(.horizontal) {
HStack(spacing: 20) {
filterButton(icon: "car.fill", color: .red, label: "Auto")
filterButton(icon: "cart.fill", color: .purple, label: "Shopping")
filterButton(icon: "laptopcomputer", color: .blue, label: "Tech")
filterButton(icon: "airplane", color: .orange, label: "Travel")
filterButton(icon: "gamecontroller.fill", color: .green, label: "Entertainment")
}
.padding(.leading, 25)
}
.scrollBounceBehavior(.basedOnSize)
.scrollIndicators(.hidden)
Spacer()
}
.padding(.top)
VStack {
Rectangle()
.fill(.thinMaterial)
.frame(height: 300)
.mask {
VStack(spacing: 0) {
LinearGradient(colors: [Color.black.opacity(0),
Color.black.opacity(0.383),
Color.black.opacity(0.707),
Color.black.opacity(0.924),
Color.black],
startPoint: .bottom,
endPoint: .top)
.frame(height: 400)
Rectangle()
}
}
Spacer()
}
.ignoresSafeArea()
VStack {
Spacer()
Rectangle()
.fill(.thinMaterial)
.frame(height: 200)
.mask {
VStack(spacing: 0) {
LinearGradient(colors: [Color.black.opacity(0),
Color.black.opacity(0.383),
Color.black.opacity(0.707),
Color.black.opacity(0.924),
Color.black],
startPoint: .top,
endPoint: .bottom)
.frame(height: 100)
Rectangle()
}
}
}
.ignoresSafeArea()
VStack(spacing: 12) {
Spacer()
Button {
showingAddItemView.toggle()
} label: {
HStack {
Image(systemName: "plus.circle")
Spacer()
.frame(width: 7)
Text("New Item")
.padding(.trailing, 3)
}
#if os(visionOS)
.padding(.vertical)
#endif
}
.padding(10)
#if os(iOS)
.background {
Capsule()
}
#endif
NavigationLink("Continue") {
}
}
.padding()