Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
3326EB702EB894AC00668ECC /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = 3326EB6F2EB894AC00668ECC /* Then */; };
3326EB732EB894B400668ECC /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3326EB722EB894B400668ECC /* SnapKit */; };
338982A92EF0205800909A38 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 338982A82EF0205800909A38 /* Lottie */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -43,6 +44,7 @@
files = (
3326EB702EB894AC00668ECC /* Then in Frameworks */,
3326EB732EB894B400668ECC /* SnapKit in Frameworks */,
338982A92EF0205800909A38 /* Lottie in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -87,6 +89,7 @@
packageProductDependencies = (
3326EB6F2EB894AC00668ECC /* Then */,
3326EB722EB894B400668ECC /* SnapKit */,
338982A82EF0205800909A38 /* Lottie */,
);
productName = "37-STUDY-iOS-ANIMATION";
productReference = 3326EB022EB8857500668ECC /* 37-STUDY-iOS-ANIMATION.app */;
Expand Down Expand Up @@ -119,6 +122,7 @@
packageReferences = (
3326EB6E2EB894AC00668ECC /* XCRemoteSwiftPackageReference "Then" */,
3326EB712EB894B400668ECC /* XCRemoteSwiftPackageReference "SnapKit" */,
338982A72EF0205800909A38 /* XCRemoteSwiftPackageReference "lottie-ios" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 3326EB032EB8857500668ECC /* Products */;
Expand Down Expand Up @@ -362,6 +366,14 @@
minimumVersion = 5.7.1;
};
};
338982A72EF0205800909A38 /* XCRemoteSwiftPackageReference "lottie-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/airbnb/lottie-ios";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 4.5.2;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand All @@ -375,6 +387,11 @@
package = 3326EB712EB894B400668ECC /* XCRemoteSwiftPackageReference "SnapKit" */;
productName = SnapKit;
};
338982A82EF0205800909A38 /* Lottie */ = {
isa = XCSwiftPackageProductDependency;
package = 338982A72EF0205800909A38 /* XCRemoteSwiftPackageReference "lottie-ios" */;
productName = Lottie;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 3326EAFA2EB8857500668ECC /* Project object */;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// 2.
let window = UIWindow(windowScene: windowScene)
// 3.
let vc = UINavigationController(rootViewController: SkeletonViewController())
let vc = UINavigationController(rootViewController: StickyHeaderViewController())
// 4.
window.rootViewController = vc
// 5.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "팔이 너무 긴 나메코 . . .좋아하는 인형을 주렁주렁 묶어보세요!9-7 오후 8시 스마트스토어 업로드 🛒.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// LottieViewController.swift
// 37-STUDY-iOS-ANIMATION
//
// Created by 김나연 on 12/15/25.
//

import UIKit

import Lottie
import Then
import SnapKit

final class LottieViewController: BaseUIViewController {
private let lottieView = LottieAnimationView(name: "bori_cake")

override func setUI() {
view.addSubviews(lottieView)
}

override func setLayout() {
lottieView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}

override func addTarget() {
startAnimation()
}
}

extension LottieViewController {
func startAnimation() {
lottieView.loopMode = .loop
lottieView.play()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// StickyHeaderViewController.swift
// 37-STUDY-iOS-ANIMATION
//
// Created by 김나연 on 12/22/25.
//

import UIKit

import SnapKit
import Then

final class StickyHeaderViewController: BaseUIViewController {

private let scrollView = UIScrollView()
private let contentView = UIView()
private let header = UIView().then {
$0.backgroundColor = .systemRed
}

private let stickyHeader = UIView().then {
$0.backgroundColor = .systemBlue
}

private let dummy = UIView()

override func setUI() {
view.addSubviews(scrollView, stickyHeader)
scrollView.addSubview(contentView)
contentView.addSubviews(header, dummy)

stickyHeader.isHidden = true
}

override func setLayout() {
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}

contentView.snp.makeConstraints {
$0.edges.equalToSuperview()
$0.width.equalToSuperview()
}

header.snp.makeConstraints {
$0.top.leading.trailing.equalToSuperview()
$0.height.equalTo(120)
}

dummy.snp.makeConstraints {
$0.top.equalTo(header.snp.bottom)
$0.leading.trailing.bottom.equalToSuperview()
$0.height.equalTo(2000)
}

stickyHeader.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide.snp.top)
$0.leading.trailing.equalToSuperview()
$0.height.equalTo(56)
}
}

override func setDelegate() {
scrollView.delegate = self
}
}

extension StickyHeaderViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {

let offsetY = scrollView.contentOffset.y
let triggerY = header.frame.maxY
let shouldShowSticky = offsetY > triggerY

stickyHeader.isHidden = !shouldShowSticky
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// StretchHeaderViewController.swift
// 37-STUDY-iOS-ANIMATION
//
// Created by 김나연 on 12/15/25.
//

import UIKit

import SnapKit
import Then

final class StretchHeaderViewController: BaseUIViewController {

private let scrollView = UIScrollView()
private let contentView = UIView()
private let imageContainerView = UIView()

private let imageView = UIImageView().then {
$0.image = .mushroom
$0.contentMode = .scaleAspectFill
}

private let label1 = UILabel().then {
$0.text = "이제"
$0.font = .systemFont(ofSize: 20, weight: .bold)
$0.textColor = .cyan
}

private let label2 = UILabel().then {
$0.text = "늘어나보겠습니다잉"
$0.font = .systemFont(ofSize: 20, weight: .bold)
$0.textColor = .cyan
}

private let label3 = UILabel().then {
$0.text = "쭈욱~~"
$0.font = .systemFont(ofSize: 20, weight: .bold)
$0.textColor = .cyan
}

private let stackView = UIStackView().then {
$0.axis = .vertical
$0.spacing = 15
}

override func setUI() {
view.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.addSubviews(imageContainerView, stackView)
imageContainerView.addSubview(imageView)
stackView.addArrangedSubviews(label1, label2, label3)
}

override func setLayout() {
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}

contentView.snp.makeConstraints {
$0.edges.equalTo(0)
$0.top.leading.trailing.equalToSuperview()
$0.width.equalTo(self.view.frame.width)
$0.height.equalTo(1000)
}

imageContainerView.snp.makeConstraints {
$0.leading.trailing.top.equalToSuperview()
$0.height.equalTo(450)
}

imageView.snp.makeConstraints {
$0.horizontalEdges.equalToSuperview()
$0.top.equalTo(view.safeAreaLayoutGuide)
$0.bottom.equalTo(imageContainerView)
}

stackView.snp.makeConstraints {
$0.top.equalTo(imageContainerView.snp.bottom).offset(50)
$0.centerX.equalToSuperview()
}
}
}