Created
October 29, 2024 02:27
-
-
Save rnmp/b73bf0a2d0b7c0d5271690e4749352bc to your computer and use it in GitHub Desktop.
Prototype of stacks in SwiftUI. See it in action: https://youtu.be/g7ag_P3TYZg
This file contains 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 | |
// The following code was generated using GPT 4-o1 with modifications and follow ups. | |
// | |
// Initial prompt: | |
// | |
// How would you code a view in swiftui where there are 3 views on top of each other | |
// (think 3 squares) and when tapped, they transition into a full window view where they | |
// are all presented in a grid? This is more or less similar to what macOS has in stacks | |
// on the dock | |
struct StackedSquaresView: View { | |
@Namespace private var animationNamespace | |
@State private var isExpanded = false | |
@State private var slideFactor = 1.0 | |
let squares = [Color.red, Color.green, Color.blue] | |
var body: some View { | |
ZStack { | |
if isExpanded { | |
ExpandedSquaresView(squares: squares, isExpanded: $isExpanded, namespace: animationNamespace) | |
.edgesIgnoringSafeArea(.all) | |
} else { | |
ZStack { | |
ForEach(0..<squares.count, id: \.self) { index in | |
squares[index] | |
.frame(width: 100, height: 100) | |
.matchedGeometryEffect(id: index, in: animationNamespace) | |
.offset(y: CGFloat(index) * 10.0 * slideFactor) | |
} | |
} | |
.onTapGesture { | |
withAnimation(.spring(duration: 0.8)) { | |
isExpanded = true | |
} | |
} | |
.onHover { next in | |
withAnimation { | |
slideFactor = next ? -2.0 : 1.0 | |
} | |
} | |
} | |
} | |
} | |
} | |
struct ExpandedSquaresView: View { | |
let squares: [Color] | |
@Binding var isExpanded: Bool | |
var namespace: Namespace.ID | |
let columns = [ | |
GridItem(.flexible()), | |
GridItem(.flexible()) | |
] | |
var body: some View { | |
ScrollView { | |
LazyVGrid(columns: columns, spacing: 20) { | |
ForEach(0..<squares.count, id: \.self) { index in | |
squares[index] | |
.frame(width: 150, height: 150) | |
.matchedGeometryEffect(id: index, in: namespace) | |
} | |
} | |
.padding() | |
} | |
.background(Color.white.opacity(0.3)) | |
.onTapGesture { | |
withAnimation(.spring(duration: 0.8)) { | |
isExpanded = false | |
} | |
} | |
} | |
} | |
#Preview { | |
StackedSquaresView() | |
#if os(macOS) | |
.frame(width: 800, height: 800) | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment