Created
May 13, 2025 01:11
-
-
Save TAATHub/ed11d5d425335d8aa31cd760945edade to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| struct ContentView: View { | |
| @State var contentOffset: CGPoint = .zero | |
| var body: some View { | |
| GeometryReader { geometry in | |
| ScrollView { | |
| VStack { | |
| HeaderView(contentOffset: $contentOffset, geometryProxy: geometry) | |
| .zIndex(1) | |
| GridView() | |
| } | |
| } | |
| .onScrollGeometryChange(for: CGPoint.self) { geometry in | |
| geometry.contentOffset | |
| } action: { _, newValue in | |
| contentOffset = newValue | |
| } | |
| .ignoresSafeArea() | |
| } | |
| } | |
| } | |
| #Preview { | |
| ContentView() | |
| } | |
| enum HeaderType { | |
| case regular, compact | |
| } | |
| struct HeaderView: View { | |
| @Binding var contentOffset: CGPoint | |
| let geometryProxy: GeometryProxy | |
| var body: some View { | |
| let isScrollingDown = contentOffset.y < 0 | |
| if contentOffset.y > 160 { | |
| VStack(alignment: .leading, spacing: 0) { | |
| HStack(spacing: 16) { | |
| IconView(size: 64) | |
| NameBioView(type: .compact) | |
| } | |
| .padding(.top, geometryProxy.safeAreaInsets.top) | |
| .padding(16) | |
| Divider() | |
| } | |
| .frame(width: geometryProxy.size.width) | |
| .background(.ultraThickMaterial) | |
| .offset(y: contentOffset.y) | |
| } else { | |
| VStack(spacing: 0) { | |
| CoverImageView(contentOffset: $contentOffset, width: geometryProxy.size.width) | |
| IconView(size: 96, withBorder: true) | |
| .padding(.top, -48) | |
| .offset(y: isScrollingDown ? contentOffset.y : 0) | |
| NameBioView(type: .regular) | |
| .offset(y: isScrollingDown ? contentOffset.y : 0) | |
| .padding(.horizontal, 16) | |
| .padding(.vertical, 16) | |
| } | |
| } | |
| } | |
| } | |
| struct IconView: View { | |
| var size: CGFloat | |
| var withBorder: Bool = false | |
| var body: some View { | |
| Image(.icon) | |
| .resizable() | |
| .scaledToFill() | |
| .frame(width: size, height: size) | |
| .clipShape(Circle()) | |
| .overlay { | |
| if withBorder { | |
| Circle().stroke(Color.white, lineWidth: 4) | |
| } | |
| } | |
| } | |
| } | |
| struct NameBioView: View { | |
| var type: HeaderType | |
| var body: some View { | |
| VStack(alignment: alignment, spacing: spacing) { | |
| Text("TAAT") | |
| .bold() | |
| .font(nameFont) | |
| Text("Software Engineer / iOS, visionOS, Unity / Metaverse, Spatial Computing") | |
| .font(bioFont) | |
| .multilineTextAlignment(bioAlignment) | |
| .fixedSize(horizontal: false, vertical: true) | |
| } | |
| } | |
| private var spacing: CGFloat { | |
| switch type { | |
| case .regular: | |
| return 8 | |
| case .compact: | |
| return 4 | |
| } | |
| } | |
| private var nameFont: Font { | |
| switch type { | |
| case .regular: | |
| return .title | |
| case .compact: | |
| return .title3 | |
| } | |
| } | |
| private var bioFont: Font { | |
| switch type { | |
| case .regular: | |
| return .body | |
| case .compact: | |
| return .footnote | |
| } | |
| } | |
| private var alignment: HorizontalAlignment { | |
| switch type { | |
| case .regular: | |
| return .center | |
| case .compact: | |
| return .leading | |
| } | |
| } | |
| private var bioAlignment: TextAlignment { | |
| switch type { | |
| case .regular: | |
| return .center | |
| case .compact: | |
| return .leading | |
| } | |
| } | |
| } | |
| struct CoverImageView: View { | |
| @Binding var contentOffset: CGPoint | |
| var width: CGFloat | |
| var body: some View { | |
| let shouldExpand = contentOffset.y < 0 | |
| Image(.cover) | |
| .resizable() | |
| .scaledToFill() | |
| .frame(width: width) | |
| .frame(height: shouldExpand ? 160 - contentOffset.y: 160) | |
| .clipped() | |
| .offset(y: shouldExpand ? contentOffset.y : 0) | |
| .blur(radius: shouldExpand ? -contentOffset.y / 80 : 0) | |
| .scaleEffect(shouldExpand ? 1 - contentOffset.y / 2000 : 1) | |
| } | |
| } | |
| struct GridView: View { | |
| var body: some View { | |
| LazyVGrid(columns: Array(repeating: GridItem(spacing: 8), count: 2)) { | |
| ForEach(0..<50) { item in | |
| RoundedRectangle(cornerRadius: 16) | |
| .frame(maxWidth: .infinity) | |
| .frame(height: 160) | |
| .foregroundStyle(.ultraThinMaterial) | |
| } | |
| } | |
| .padding(.horizontal, 16) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment