60 lines
1.6 KiB
Swift
60 lines
1.6 KiB
Swift
//
|
|
// ParallaxHeaderView.swift
|
|
// Nextcloud Cookbook iOS Client
|
|
//
|
|
// Created by Vincent Meilinger on 26.02.24.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
|
|
|
|
struct ParallaxHeader<Content: View, Space: Hashable>: View {
|
|
let content: () -> Content
|
|
let coordinateSpace: Space
|
|
let defaultHeight: CGFloat
|
|
|
|
init(
|
|
coordinateSpace: Space,
|
|
defaultHeight: CGFloat,
|
|
@ViewBuilder _ content: @escaping () -> Content
|
|
) {
|
|
self.content = content
|
|
self.coordinateSpace = coordinateSpace
|
|
self.defaultHeight = defaultHeight
|
|
}
|
|
|
|
var body: some View {
|
|
GeometryReader { proxy in
|
|
let offset = offset(for: proxy)
|
|
let heightModifier = heightModifier(for: proxy)
|
|
let blurRadius = min(
|
|
heightModifier / 20,
|
|
max(10, heightModifier / 20)
|
|
)
|
|
content()
|
|
.edgesIgnoringSafeArea(.horizontal)
|
|
.frame(
|
|
width: proxy.size.width,
|
|
height: proxy.size.height + heightModifier
|
|
)
|
|
.offset(y: offset)
|
|
.blur(radius: blurRadius)
|
|
}.frame(height: defaultHeight)
|
|
}
|
|
|
|
|
|
private func offset(for proxy: GeometryProxy) -> CGFloat {
|
|
let frame = proxy.frame(in: .named(coordinateSpace))
|
|
if frame.minY < 0 {
|
|
return -frame.minY * 0.8
|
|
}
|
|
return -frame.minY
|
|
}
|
|
|
|
private func heightModifier(for proxy: GeometryProxy) -> CGFloat {
|
|
let frame = proxy.frame(in: .named(coordinateSpace))
|
|
return max(0, frame.minY)
|
|
}
|
|
}
|