Last active
February 27, 2025 13:55
-
-
Save mishamoix/c1a0b0d52dddcfd3d69df5906091e21a to your computer and use it in GitHub Desktop.
SwiftUI animation. @namespace and .matchedGeometryEffect
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 private var isProfileExpanded = false | |
@Namespace private var profileAnimation | |
private let gradient = LinearGradient( | |
gradient: Gradient(colors: [.purple, .orange]), | |
startPoint: .topLeading, | |
endPoint: .bottomTrailing | |
) | |
private let gradient2 = LinearGradient( | |
gradient: Gradient(colors: [.green, .yellow]), | |
startPoint: .topLeading, | |
endPoint: .bottomTrailing | |
) | |
var body: some View { | |
VStack { | |
if isProfileExpanded { | |
expandedProfileView | |
} else { | |
collapsedProfileView | |
} | |
videoList | |
} | |
} | |
var collapsedProfileView: some View { | |
HStack { | |
profileImage | |
.matchedGeometryEffect(id: "profileAvatar", in: profileAnimation) | |
.frame(width: 60, height: 60) | |
VStack(alignment: .leading) { | |
Text("Profile Name") | |
.font(.title) | |
.bold() | |
.matchedGeometryEffect(id: "profileName", in: profileAnimation) | |
Text("iOS Developer") | |
.foregroundColor(.secondary) | |
.matchedGeometryEffect(id: "profileJob", in: profileAnimation) | |
} | |
Spacer() | |
} | |
.padding() | |
} | |
var expandedProfileView: some View { | |
VStack { | |
profileImage | |
.matchedGeometryEffect(id: "profileAvatar", in: profileAnimation) | |
.frame(width: 130, height: 130) | |
VStack { | |
Text("Profile Name") | |
.font(.title) | |
.bold() | |
.matchedGeometryEffect(id: "profileName", in: profileAnimation) | |
Text("iOS Developer") | |
.foregroundColor(.pink) | |
.matchedGeometryEffect(id: "profileJob", in: profileAnimation) | |
Text("Check this Cool description, Check this Cool description, Check this Cool description.") | |
.padding() | |
} | |
} | |
.padding() | |
} | |
var profileImage: some View { | |
RoundedRectangle(cornerSize: CGSize(width: 6, height: 6)) | |
.fill(isProfileExpanded ? gradient : gradient2) | |
.onTapGesture { | |
withAnimation(.spring()) { | |
isProfileExpanded.toggle() | |
} | |
} | |
} | |
var videoList: some View { | |
List { | |
ForEach(0...5, id: \.self) { _ in | |
ZStack { | |
RoundedRectangle(cornerRadius: 8) | |
.frame(height: 180) | |
.foregroundColor(.gray.opacity(0.5)) | |
Image(systemName: "play.fill") | |
.resizable() | |
.frame(width: 30, height: 30) | |
.opacity(0.3) | |
} | |
.padding(.vertical) | |
} | |
.listRowSeparator(.hidden) | |
} | |
.listStyle(.plain) | |
} | |
} | |
#Preview { | |
ContentView() | |
.preferredColorScheme(.dark) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment