Last active
May 29, 2025 00:54
-
-
Save gtokman/b4897e1879610faa57330a4bf30946a8 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 { | |
var response: LooksResponse { | |
try! LooksResponse.decode() | |
} | |
@State var isFullScreen = false | |
var body: some View { | |
GeometryReader { proxy in | |
let fullImageHeight = proxy.frame(in: .global).height - proxy.safeAreaInsets.bottom | |
VStack { | |
ScrollView(.horizontal, showsIndicators: false) { | |
HStack(spacing: 0) { | |
ForEach(response.looks) { | |
ImageView(for: $0, fullImageHeight: fullImageHeight) | |
.offset(y: isFullScreen ? 0 : (proxy.safeAreaInsets.bottom * 2)) | |
} | |
.scrollTransition(transition: { content, phase in | |
return content | |
.opacity(phase.isIdentity ? 1 : 0.5) | |
.blur(radius: phase.isIdentity ? 0: 10) | |
.scaleEffect( | |
x: phase.isIdentity ? 1 : 0.75, | |
y: phase.isIdentity ? 1 : 0.75) | |
}) | |
.containerRelativeFrame(.horizontal) | |
} | |
.sensoryFeedback(.selection, trigger: isFullScreen) | |
.frame(height: isFullScreen ? fullImageHeight : fullImageHeight / 2) | |
.clipped() | |
.overlay(alignment: .bottom) { | |
LinearGradient( | |
gradient: Gradient(stops: [ | |
.init(color: .white, location: 0), | |
.init(color: .white.opacity(0.8), location: 0.25), | |
.init(color: .white.opacity(0), location: 1) | |
]), | |
startPoint: .bottom, | |
endPoint: .top | |
) | |
.frame(height: 5) | |
.opacity(isFullScreen ? 0 : 1) | |
.allowsHitTesting(false) | |
} | |
} | |
if !isFullScreen{ | |
Spacer() | |
} | |
} | |
.scrollTargetBehavior(.paging) | |
} | |
} | |
@ViewBuilder func ImageView(for look: Look, fullImageHeight: CGFloat) -> some View { | |
CachedAsyncImage(url: look.imageUrl) { phase in | |
if let image = phase.image { | |
image.resizable() | |
.aspectRatio(contentMode: .fit) | |
.frame(height: isFullScreen ? fullImageHeight : fullImageHeight / 2) | |
} else if phase.error != nil { | |
Image(systemName: "xmark.circle.fill") | |
.resizable() | |
.frame(width: 24, height: 24) | |
.foregroundStyle(.red) | |
} else { | |
ProgressView() | |
} | |
} | |
.onTapGesture { | |
withAnimation(.smooth) { | |
isFullScreen.toggle() | |
} | |
} | |
} | |
} | |
#Preview { | |
ContentView() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment