The masking method might work for scroll views too, for those who monitor the frames of every subview of the scroll view. You could possibly use a struct like this:
struct ScrollContentFrame: Identifiable {
let id: AnyHashable
let body: Anchor
let form: AnyShape
}
I am maintaining issues very common right here by utilizing AnyHashable
and AnyShape
. If that is only a one-off impact you need to do, I’d suggest utilizing an applicable ID kind, and if the form is understood and fixed, take away form
.
Subsequent, write a desire key that collects an array of those,
struct ScrollContentFramesKey: PreferenceKey {
static var defaultValue: [ScrollContentFrame] { [] }
static func scale back(worth: inout [ScrollContentFrame], nextValue: () -> [ScrollContentFrame]) {
worth.append(contentsOf: nextValue())
}
}
Set the desire key utilizing an anchorPreference
,
.anchorPreference(key: ScrollContentFramesKey.self, worth: .bounds) { anchor in
[
ScrollContentFrame(
id: i,
frame: anchor,
shape: AnyShape(RoundedRectangle(cornerRadius: 16))
)
]
}
The colour-blended linear gradient could be added as an overlayPreferenceValue
as a substitute of ZStack
.
.overlayPreferenceValue(ScrollContentFramesKey.self) { scrollContentFrames in
LinearGradient(
colours: [.blue, .orange],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.allowsHitTesting(false)
.masks {
GeometryReader { proxy in
ForEach(scrollContentFrames) { content material in
let body = proxy[content.frame]
content material.form
.body(width: body.width, top: body.top)
.place(x: body.midX, y: body.midY)
}
}
}
.blendMode(.coloration)
.ignoresSafeArea()
}
Full code for the view:
struct ContentView: View {
var physique: some View {
ZStack {
LinearGradient(
colours: [.purple, .pink],
startPoint: .high,
endPoint: .backside
)
.ignoresSafeArea()
ScrollView {
LazyVStack(spacing: 20) {
ForEach(0..<10) { i in
RoundedRectangle(cornerRadius: 16)
.fill(.white)
.body(top: 120)
.overlay(
Textual content("Card (i)")
.font(.headline)
.foregroundColor(.crimson)
)
.anchorPreference(key: ScrollContentFramesKey.self, worth: .bounds) { anchor in
[
ScrollContentFrame(
id: i,
frame: anchor,
shape: AnyShape(RoundedRectangle(cornerRadius: 16))
)
]
}
.padding(.horizontal)
}
}
.padding(.vertical, 50)
}
.background(Shade.clear)
.overlayPreferenceValue(ScrollContentFramesKey.self) { scrollContentFrames in
LinearGradient(
colours: [.blue, .orange],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.allowsHitTesting(false)
.masks {
GeometryReader { proxy in
ForEach(scrollContentFrames) { content material in
let body = proxy[content.frame]
content material.form
.body(width: body.width, top: body.top)
.place(x: body.midX, y: body.midY)
}
}
}
.blendMode(.coloration)
.ignoresSafeArea()
}
}
}
}