Skip to content

Instantly share code, notes, and snippets.

@gtokman
Last active May 29, 2025 00:54
Show Gist options
  • Save gtokman/b4897e1879610faa57330a4bf30946a8 to your computer and use it in GitHub Desktop.
Save gtokman/b4897e1879610faa57330a4bf30946a8 to your computer and use it in GitHub Desktop.
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