diff --git a/.DS_Store b/.DS_Store index 7c7fdeb..e3d2708 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.pbxproj b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.pbxproj index f12c171..094219c 100644 --- a/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.pbxproj +++ b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.pbxproj @@ -6,6 +6,10 @@ objectVersion = 77; objects = { +/* Begin PBXBuildFile section */ + 970061E52CBA452E002DA8BD /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 970061E42CBA452E002DA8BD /* SnapKit */; }; +/* End PBXBuildFile section */ + /* Begin PBXFileReference section */ 9742D52B2CB108C70011D0A4 /* 35-Seminar-hee1.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "35-Seminar-hee1.app"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -36,6 +40,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 970061E52CBA452E002DA8BD /* SnapKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -78,6 +83,7 @@ ); name = "35-Seminar-hee1"; packageProductDependencies = ( + 970061E42CBA452E002DA8BD /* SnapKit */, ); productName = "35-Seminar-hee1"; productReference = 9742D52B2CB108C70011D0A4 /* 35-Seminar-hee1.app */; @@ -107,6 +113,9 @@ ); mainGroup = 9742D5222CB108C70011D0A4; minimizedProjectReferenceProxies = 1; + packageReferences = ( + 970061E32CBA452E002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */, + ); preferredProjectObjectVersion = 77; productRefGroup = 9742D52C2CB108C70011D0A4 /* Products */; projectDirPath = ""; @@ -333,6 +342,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 970061E32CBA452E002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.7.1; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 970061E42CBA452E002DA8BD /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 970061E32CBA452E002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 9742D5232CB108C70011D0A4 /* Project object */; } diff --git a/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3f64b3c --- /dev/null +++ b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "dd27728c8848101841bd8d45243ef43144e233aa3767c82656934b73447347b8", + "pins" : [ + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "2842e6e84e82eb9a8dac0100ca90d9444b0307f4", + "version" : "5.7.1" + } + } + ], + "version" : 3 +} diff --git a/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate index 4ecf246..501aef8 100644 Binary files a/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate and b/35-Seminar-hee1/35-Seminar-hee1.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/35-Seminar-hee1/35-Seminar-hee1/AppDelegate.swift b/35-Seminar-hee1/35-Seminar-hee1/AppDelegate.swift index 7a8c64b..1dfe46a 100644 --- a/35-Seminar-hee1/35-Seminar-hee1/AppDelegate.swift +++ b/35-Seminar-hee1/35-Seminar-hee1/AppDelegate.swift @@ -6,7 +6,7 @@ // import UIKit - +//$0, $1, $2 ... - param을 축약 @main class AppDelegate: UIResponder, UIApplicationDelegate { diff --git a/35-Seminar-hee1/35-Seminar-hee1/DetailViewController.swift b/35-Seminar-hee1/35-Seminar-hee1/DetailViewController.swift deleted file mode 100644 index dc3b67d..0000000 --- a/35-Seminar-hee1/35-Seminar-hee1/DetailViewController.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// DetailViewController.swift -// 35-Seminar-hee1 -// -// Created by 김희은 on 10/5/24. -// - -import UIKit - -class DetailViewController: UIViewController { - - private let titleLabel: UILabel = { - let label = UILabel() - label.textColor = .white - label.font = .systemFont(ofSize: 30) - - return label - }() - - private lazy var backButton: UIButton = { - let button = UIButton() - button.setTitle("뒤로가기", for: .normal) - button.backgroundColor = .white - button.setTitleColor(.red, for: .normal) - button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) - return button - }() - - - private var receivedTitle: String? - - override func viewDidLoad() { - super.viewDidLoad() - setStyle() - setUI() - setLayout() - } - - - private func setStyle() { - self.view.backgroundColor = .red - } - - private func setUI() { - [titleLabel, backButton].forEach { - $0.translatesAutoresizingMaskIntoConstraints = false - self.view.addSubview($0) - } - } - - private func setLayout() { - - NSLayoutConstraint.activate( - [ - titleLabel.topAnchor.constraint( - equalTo: view.safeAreaLayoutGuide.topAnchor, - constant: 50 - ), - titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), - backButton.topAnchor.constraint( - equalTo: titleLabel.bottomAnchor, - constant: 20 - ), - backButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), - backButton.heightAnchor.constraint(equalToConstant: 44), - backButton.widthAnchor.constraint(equalToConstant: 300), - ] - ) - } - - @objc func backButtonTapped() { - if self.navigationController == nil { - self.dismiss(animated: true) - } else { - self.navigationController?.popViewController(animated: true) - } - } - - func updateUI() { - self.titleLabel.text = receivedTitle - } - - func dataBine( - title: String - ) { - self.receivedTitle = title - updateUI() - } - -} diff --git a/35-Seminar-hee1/35-Seminar-hee1/ViewController.swift b/35-Seminar-hee1/35-Seminar-hee1/ViewController.swift index 5b33f82..7565c2b 100644 --- a/35-Seminar-hee1/35-Seminar-hee1/ViewController.swift +++ b/35-Seminar-hee1/35-Seminar-hee1/ViewController.swift @@ -6,7 +6,7 @@ // import UIKit - +import SnapKit class ViewController: UIViewController { private let titleLabel: UILabel = { @@ -43,6 +43,12 @@ class ViewController: UIViewController { return textView }() + public let nickNameLabel: UILabel = { + let label = UILabel() + label.text = " " + return label + }() + private lazy var nextButton: UIButton = { let button = UIButton() button.setTitle("다음", for: .normal) @@ -64,11 +70,10 @@ class ViewController: UIViewController { private var pushMode = true { didSet { - updateUI() // pushMode 변경 시마다 updateUI()호출 + updateUI() } } - override func viewDidLoad() { super.viewDidLoad() setStyle() @@ -83,13 +88,14 @@ class ViewController: UIViewController { } private func setUI() { - [titleLabel, imageView, subTitleLabel,feedbackTextView, nextButton, pushModeToggleButton].forEach { + [titleLabel, imageView, subTitleLabel,feedbackTextView, nickNameLabel, nextButton, pushModeToggleButton].forEach { $0.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview($0) } } private func setLayout() { + // - Todo : SnapKit통해 오토레이아웃 다시 잡기 - // NSLayoutConstraint.activate( [ titleLabel.topAnchor.constraint( @@ -122,9 +128,13 @@ class ViewController: UIViewController { constant: -20 ), feedbackTextView.bottomAnchor.constraint( - equalTo: nextButton.topAnchor, constant: -20 + equalTo: nickNameLabel.topAnchor, constant: -20 ), + nickNameLabel.topAnchor.constraint(equalTo: feedbackTextView.bottomAnchor, constant: 20), + nickNameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), + nickNameLabel.bottomAnchor.constraint(equalTo: nextButton.topAnchor, constant: -20), + nextButton.bottomAnchor.constraint(equalTo: pushModeToggleButton.topAnchor, constant: -20), nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), nextButton.heightAnchor.constraint(equalToConstant: 50), @@ -156,13 +166,19 @@ class ViewController: UIViewController { transitionToNextViewController() } private func transitionToNextViewController() { - let nextViewController = DetailViewController() + let nextViewController = DetailViewController_Closer() - guard let title = feedbackTextView.text else { - return + nextViewController.completionHandler = { [weak self] nickname in + guard let self else { return } + self.nickNameLabel.text = nickname } - nextViewController.dataBine(title: title) + //nextViewController.delegate = self +// guard let title = feedbackTextView.text else { +// return +// } + + //nextViewController.dataBine(title: title) if pushMode { self.navigationController?.pushViewController( @@ -183,3 +199,9 @@ class ViewController: UIViewController { } } + +extension ViewController: NicknameDelegate { + func dataBind(nickname: String) { + self.nickNameLabel.text = nickname + } +} diff --git a/35-Seminar-hee1/35-Seminar-hee1/week1/DetailViewController.swift b/35-Seminar-hee1/35-Seminar-hee1/week1/DetailViewController.swift new file mode 100644 index 0000000..15fde4f --- /dev/null +++ b/35-Seminar-hee1/35-Seminar-hee1/week1/DetailViewController.swift @@ -0,0 +1,125 @@ +// +// DetailViewController.swift +// 35-Seminar-hee1 +// +// Created by 김희은 on 10/5/24. +// + +import UIKit +import SnapKit + +protocol NicknameDelegate: AnyObject { + func dataBind(nickname: String) // 다음화면에서 이전화면으로 Data를 Delegate할 것. +} + +class DetailViewController: UIViewController { + + weak var delegate: NicknameDelegate? + // delegate를 사용하지 않고 클로저를 사용. + + private let titleLabel: UILabel = { + let label = UILabel() + label.textColor = .white + label.font = .systemFont(ofSize: 30) + + return label + }() + + private let nicknameTextField: UITextField = { + let textField = UITextField() + + textField.placeholder = "입력하시오." + textField.textColor = .black + textField.backgroundColor = .white + + return textField + }() + + private lazy var delegateButton: UIButton = { + let button = UIButton() + button.setTitle("데이터 전달하기", for: .normal) + button.backgroundColor = .white + button.setTitleColor(.red, for: .normal) + button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + return button + }() + + private lazy var backButton: UIButton = { + let button = UIButton() + button.setTitle("뒤로가기", for: .normal) + button.backgroundColor = .white + button.setTitleColor(.red, for: .normal) + button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + return button + }() + + private var receivedTitle: String? + + override func viewDidLoad() { + super.viewDidLoad() + setStyle() + setUI() + setLayout() + } + + + private func setStyle() { + self.view.backgroundColor = .red + } + + private func setUI() { + [titleLabel, nicknameTextField, delegateButton, backButton].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview($0) + } + } + + private func setLayout() { + // SnapKit을 통해 오토레이아웃 코드 변경하기. + NSLayoutConstraint.activate( + [ + titleLabel.topAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.topAnchor, + constant: 50 + ), + titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), + + nicknameTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20), + nicknameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20), + nicknameTextField.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20), + + delegateButton.topAnchor.constraint(equalTo: nicknameTextField.bottomAnchor, constant: 20), + delegateButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + delegateButton.heightAnchor.constraint(equalToConstant: 44), + delegateButton.widthAnchor.constraint(equalToConstant: 300), + + + backButton.bottomAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.bottomAnchor, + constant: -20 + ), + backButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + backButton.heightAnchor.constraint(equalToConstant: 44), + backButton.widthAnchor.constraint(equalToConstant: 300), + ] + ) + } + + @objc func backButtonTapped() { + if let nickname = nicknameTextField.text { + delegate?.dataBind(nickname: nickname) + } + self.navigationController?.popViewController(animated: true) + } + + func updateUI() { + self.titleLabel.text = receivedTitle + } + + func dataBine( + title: String + ) { + self.receivedTitle = title + updateUI() + } +} diff --git a/35-Seminar-hee1/35-Seminar-hee1/week2/DetailViewController_Closer.swift b/35-Seminar-hee1/35-Seminar-hee1/week2/DetailViewController_Closer.swift new file mode 100644 index 0000000..7f239a9 --- /dev/null +++ b/35-Seminar-hee1/35-Seminar-hee1/week2/DetailViewController_Closer.swift @@ -0,0 +1,124 @@ +// +// DetailViewController_Closer.swift +// 35-Seminar-hee1 +// +// Created by 김희은 on 10/12/24. +// + +import UIKit +import SnapKit + +protocol DetailDelegate: AnyObject { + func dataBind(nickname: String) // 다음화면에서 이전화면으로 Data +} +class DetailViewController_Closer: UIViewController { + weak var delegate: DetailDelegate? + // delegate를 사용하지 않고 클로저를 사용. + var completionHandler: ((String) -> ())? + + + private let titleLabel: UILabel = { + let label = UILabel() + label.textColor = .white + label.font = .systemFont(ofSize: 30) + + return label + }() + + private let nicknameTextField: UITextField = { + let textField = UITextField() + + textField.placeholder = "입력하시오." + textField.textColor = .black + textField.backgroundColor = .white + + return textField + }() + + private lazy var delegateButton: UIButton = { + let button = UIButton() + button.setTitle("데이터 전달하기", for: .normal) + button.backgroundColor = .white + button.setTitleColor(.red, for: .normal) + button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + return button + }() + + private lazy var backButton: UIButton = { + let button = UIButton() + button.setTitle("뒤로가기", for: .normal) + button.backgroundColor = .white + button.setTitleColor(.red, for: .normal) + button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + return button + }() + + private var receivedTitle: String? + + override func viewDidLoad() { + super.viewDidLoad() + setStyle() + setUI() + setLayout() + } + + + private func setStyle() { + self.view.backgroundColor = .red + } + + private func setUI() { + [titleLabel, nicknameTextField, delegateButton, backButton].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview($0) + } + } + + private func setLayout() { + // SnapKit을 통해 오토레이아웃 코드 변경하기. + NSLayoutConstraint.activate( + [ + titleLabel.topAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.topAnchor, + constant: 50 + ), + titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), + + nicknameTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20), + nicknameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20), + nicknameTextField.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20), + + delegateButton.topAnchor.constraint(equalTo: nicknameTextField.bottomAnchor, constant: 20), + delegateButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + delegateButton.heightAnchor.constraint(equalToConstant: 44), + delegateButton.widthAnchor.constraint(equalToConstant: 300), + + + backButton.bottomAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.bottomAnchor, + constant: -20 + ), + backButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + backButton.heightAnchor.constraint(equalToConstant: 44), + backButton.widthAnchor.constraint(equalToConstant: 300), + ] + ) + } + + @objc func backButtonTapped() { + guard let nickname = nicknameTextField.text else { return } + completionHandler?(nickname) + self.navigationController?.popViewController(animated: true) + } + + func updateUI() { + self.titleLabel.text = receivedTitle + } + + func dataBine( + title: String + ) { + self.receivedTitle = title + updateUI() + } +} diff --git a/35-Seminar-hee2/.DS_Store b/35-Seminar-hee2/.DS_Store new file mode 100644 index 0000000..964b238 Binary files /dev/null and b/35-Seminar-hee2/.DS_Store differ diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.pbxproj b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4cd06ca --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.pbxproj @@ -0,0 +1,383 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 970062032CBA5B12002DA8BD /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 970062022CBA5B12002DA8BD /* SnapKit */; }; + 977386B52CCAA334009A5A96 /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = 977386B42CCAA334009A5A96 /* Then */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 970061C72CBA40C9002DA8BD /* 35-Seminar-hee2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "35-Seminar-hee2.app"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 970061D92CBA40CA002DA8BD /* Exceptions for "35-Seminar-hee2" folder in "35-Seminar-hee2" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 970061C62CBA40C9002DA8BD /* 35-Seminar-hee2 */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 970061C92CBA40C9002DA8BD /* 35-Seminar-hee2 */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 970061D92CBA40CA002DA8BD /* Exceptions for "35-Seminar-hee2" folder in "35-Seminar-hee2" target */, + ); + path = "35-Seminar-hee2"; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 970061C42CBA40C9002DA8BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 970062032CBA5B12002DA8BD /* SnapKit in Frameworks */, + 977386B52CCAA334009A5A96 /* Then in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 970061BE2CBA40C9002DA8BD = { + isa = PBXGroup; + children = ( + 970061C92CBA40C9002DA8BD /* 35-Seminar-hee2 */, + 970061C82CBA40C9002DA8BD /* Products */, + ); + sourceTree = ""; + }; + 970061C82CBA40C9002DA8BD /* Products */ = { + isa = PBXGroup; + children = ( + 970061C72CBA40C9002DA8BD /* 35-Seminar-hee2.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 970061C62CBA40C9002DA8BD /* 35-Seminar-hee2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 970061DA2CBA40CA002DA8BD /* Build configuration list for PBXNativeTarget "35-Seminar-hee2" */; + buildPhases = ( + 970061C32CBA40C9002DA8BD /* Sources */, + 970061C42CBA40C9002DA8BD /* Frameworks */, + 970061C52CBA40C9002DA8BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 970061C92CBA40C9002DA8BD /* 35-Seminar-hee2 */, + ); + name = "35-Seminar-hee2"; + packageProductDependencies = ( + 970062022CBA5B12002DA8BD /* SnapKit */, + 977386B42CCAA334009A5A96 /* Then */, + ); + productName = "35-Seminar-hee2"; + productReference = 970061C72CBA40C9002DA8BD /* 35-Seminar-hee2.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 970061BF2CBA40C9002DA8BD /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1600; + LastUpgradeCheck = 1600; + TargetAttributes = { + 970061C62CBA40C9002DA8BD = { + CreatedOnToolsVersion = 16.0; + }; + }; + }; + buildConfigurationList = 970061C22CBA40C9002DA8BD /* Build configuration list for PBXProject "35-Seminar-hee2" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 970061BE2CBA40C9002DA8BD; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + 970062012CBA5B12002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */, + 977386B32CCAA334009A5A96 /* XCRemoteSwiftPackageReference "Then" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = 970061C82CBA40C9002DA8BD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 970061C62CBA40C9002DA8BD /* 35-Seminar-hee2 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 970061C52CBA40C9002DA8BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 970061C32CBA40C9002DA8BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 970061DB2CBA40CA002DA8BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = N2225VQ3TM; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "35-Seminar-hee2/Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.-5-Seminar-hee2"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 970061DC2CBA40CA002DA8BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = N2225VQ3TM; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "35-Seminar-hee2/Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.-5-Seminar-hee2"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 970061DD2CBA40CA002DA8BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 970061DE2CBA40CA002DA8BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 970061C22CBA40C9002DA8BD /* Build configuration list for PBXProject "35-Seminar-hee2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 970061DD2CBA40CA002DA8BD /* Debug */, + 970061DE2CBA40CA002DA8BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 970061DA2CBA40CA002DA8BD /* Build configuration list for PBXNativeTarget "35-Seminar-hee2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 970061DB2CBA40CA002DA8BD /* Debug */, + 970061DC2CBA40CA002DA8BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 970062012CBA5B12002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.7.1; + }; + }; + 977386B32CCAA334009A5A96 /* XCRemoteSwiftPackageReference "Then" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/devxoul/Then"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 970062022CBA5B12002DA8BD /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 970062012CBA5B12002DA8BD /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + 977386B42CCAA334009A5A96 /* Then */ = { + isa = XCSwiftPackageProductDependency; + package = 977386B32CCAA334009A5A96 /* XCRemoteSwiftPackageReference "Then" */; + productName = Then; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 970061BF2CBA40C9002DA8BD /* Project object */; +} diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..da17c27 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,24 @@ +{ + "originHash" : "dc78d9f78c6dffeef10c87cabc223dde5b29ad30f0c1897eba28f817c2359a8a", + "pins" : [ + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "2842e6e84e82eb9a8dac0100ca90d9444b0307f4", + "version" : "5.7.1" + } + }, + { + "identity" : "then", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devxoul/Then", + "state" : { + "revision" : "d41ef523faef0f911369f79c0b96815d9dbb6d7a", + "version" : "3.0.0" + } + } + ], + "version" : 3 +} diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..4fc089a Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/project.xcworkspace/xcuserdata/hee.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..7c92da5 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcschemes/xcschememanagement.plist b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..71a70b3 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2.xcodeproj/xcuserdata/hee.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + 35-Seminar-hee2.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/35-Seminar-hee2/35-Seminar-hee2/.DS_Store b/35-Seminar-hee2/35-Seminar-hee2/.DS_Store new file mode 100644 index 0000000..4db9e9e Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2/.DS_Store differ diff --git a/35-Seminar-hee2/35-Seminar-hee2/App/AppDelegate.swift b/35-Seminar-hee2/35-Seminar-hee2/App/AppDelegate.swift new file mode 100644 index 0000000..271e5a0 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/App/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/12/24. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/35-Seminar-hee2/35-Seminar-hee2/App/Base.lproj/LaunchScreen.storyboard b/35-Seminar-hee2/35-Seminar-hee2/App/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/App/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/35-Seminar-hee2/35-Seminar-hee2/App/SceneDelegate.swift b/35-Seminar-hee2/35-Seminar-hee2/App/SceneDelegate.swift new file mode 100644 index 0000000..a80b7b3 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/App/SceneDelegate.swift @@ -0,0 +1,25 @@ +// +// SceneDelegate.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/12/24. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene( + _ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions + ) { + guard let windowScene = (scene as? UIWindowScene) else { return } + self.window = UIWindow(windowScene: windowScene) + let navigationController = UINavigationController(rootViewController: FinanceChartViewController()) + self.window?.rootViewController = navigationController + self.window?.makeKeyAndVisible() + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Info.plist b/35-Seminar-hee2/35-Seminar-hee2/Info.plist new file mode 100644 index 0000000..0eb786d --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Info.plist @@ -0,0 +1,23 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + + diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AccentColor.colorset/Contents.json b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..274babb --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/Contents.json b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/Contents.json b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/Contents.json new file mode 100644 index 0000000..200d75c --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon_toss.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/icon_toss.png b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/icon_toss.png new file mode 100644 index 0000000..5e5e38a Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/icon_toss.imageset/icon_toss.png differ diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/Contents.json b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/Contents.json new file mode 100644 index 0000000..6bb7e89 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "preview.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/preview.png b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/preview.png new file mode 100644 index 0000000..743abcf Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2/Resource/Assets.xcassets/preview.imageset/preview.png differ diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/.DS_Store b/35-Seminar-hee2/35-Seminar-hee2/Source/.DS_Store new file mode 100644 index 0000000..1f29bb3 Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2/Source/.DS_Store differ diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Controller/ChartViewController.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Controller/ChartViewController.swift new file mode 100644 index 0000000..bf6ec52 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Controller/ChartViewController.swift @@ -0,0 +1,66 @@ +// +// ChartViewController.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/26/24. +// + +import SnapKit +import UIKit +import Then + +class ChartViewController: UIViewController { + + private let chartTableView = UITableView() + private let appList = App.mockData + + override func viewDidLoad() { + super.viewDidLoad() + + setUI() + setStyle() + setLayout() + } + + private func setUI() { + self.view.addSubview(chartTableView) + } + + private func setStyle() { + chartTableView.do { + $0.register( + ChartCell.self, + forCellReuseIdentifier: ChartCell.identifier + ) + $0.rowHeight = 100 + $0.delegate = self + $0.dataSource = self + } + } + + private func setLayout() { + chartTableView.snp.makeConstraints { + $0.leading.trailing.top.bottom.equalToSuperview() + } + } +} + +extension ChartViewController: UITableViewDelegate{} + +extension ChartViewController: UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return appList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = chartTableView.dequeueReusableCell( + withIdentifier: ChartCell.identifier, + for: indexPath + ) as? ChartCell else { + return UITableViewCell() + } + cell.configure(app: appList[indexPath.row]) + return cell + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/App.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/App.swift new file mode 100644 index 0000000..64e0674 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/App.swift @@ -0,0 +1,102 @@ +// +// App.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/26/24. +// + +import UIKit + +struct App { + let iconImage: UIImage + let ranking: Int + let title: String + let subtitle: String + let category: String + var downloadState: DownloadState +} + +extension App { + static let mockData: [App] = [ + App( + iconImage: UIImage(systemName: "1.square.fill")!, + ranking: 1, + title: "1", + subtitle: "1-1", + category: "소셜 네트워킹", + downloadState: .installed + ), + App( + iconImage: UIImage(systemName: "2.square.fill")!, + ranking: 2, + title: "2", + subtitle: "2-1", + category: "엔터테인먼트", + downloadState: .installed + ), + App( + iconImage: UIImage(systemName: "3.square.fill")!, + ranking: 3, + title: "토스", + subtitle: "금융이 쉬워진다", + category: "", + downloadState: .download + ), + App( + iconImage: UIImage(systemName: "4.square.fill")!, + ranking: 4, + title: "4", + subtitle: "영화와 TV 프로그램 시청", + category: "엔터테인먼트", + downloadState: .installed + ), + App( + iconImage: UIImage(systemName: "5.square.fill")!, + ranking: 5, + title: "5", + subtitle: "이메일과 캘린더", + category: "생산성", + downloadState: .redownload + ), + App( + iconImage: UIImage(systemName: "6.square.fill")!, + ranking: 6, + title: "6", + subtitle: "친구와 소통하기", + category: "소셜 네트워킹", + downloadState: .download + ), + App( + iconImage: UIImage(systemName: "7.square.fill")!, + ranking: 7, + title: "7", + subtitle: "게이머를 위한 채팅", + category: "소셜 네트워킹", + downloadState: .installed + ), + App( + iconImage: UIImage(systemName: "8.square.fill")!, + ranking: 8, + title: "8", + subtitle: "검색과 클라우드 서비스", + category: "유틸리티", + downloadState: .redownload + ), + App( + iconImage: UIImage(systemName: "9.square.fill")!, + ranking: 9, + title: "9", + subtitle: "무료 메시지와 통화", + category: "소셜 네트워킹", + downloadState: .update + ), + App( + iconImage: UIImage(systemName: "10.square.fill")!, + ranking: 10, + title: "10", + subtitle: "검색과 클라우드 서비스", + category: "유틸리티", + downloadState: .download + ) + ] +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/DownloadState.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/DownloadState.swift new file mode 100644 index 0000000..48f7c02 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/Model/DownloadState.swift @@ -0,0 +1,15 @@ +// +// DownloadState.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/26/24. +// + +import Foundation + +enum DownloadState { + case installed + case download + case redownload + case update +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/View/ChartCell.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/View/ChartCell.swift new file mode 100644 index 0000000..23d535c --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Chart/View/ChartCell.swift @@ -0,0 +1,79 @@ +// +// ChartCell.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/26/24. +// + +import SnapKit +import UIKit +import Then + +class ChartCell: UITableViewCell { + + private lazy var iconImageView = UIImageView() + private let rankingLabel = UILabel() + private let titleLabel = UILabel() + private let subTitleLabel = UILabel() + private let categoryLabel = UILabel() + private lazy var downloadStateButton = UIButton() + + static let identifier = "ChartCell" + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setStyle() { + } + + private func setUI() { + [iconImageView, rankingLabel, titleLabel, subTitleLabel, categoryLabel, downloadStateButton].forEach { + addSubview($0) + } + } + + private func setLayout() { + iconImageView.snp.makeConstraints { + $0.leading.equalToSuperview().offset(20) + $0.top.equalToSuperview().offset(10) + $0.width.height.equalTo(50) + } + rankingLabel.snp.makeConstraints { + $0.leading.equalTo(iconImageView.snp.trailing).offset(10) + $0.top.equalToSuperview().offset(10) + } + titleLabel.snp.makeConstraints { + $0.leading.equalTo(rankingLabel.snp.trailing).offset(10) + $0.top.equalTo(rankingLabel) + } + subTitleLabel.snp.makeConstraints { + $0.leading.equalTo(titleLabel.snp.leading) + $0.top.equalTo(titleLabel.snp.bottom) + } + categoryLabel.snp.makeConstraints { + $0.leading.equalTo(subTitleLabel.snp.leading) + $0.top.equalTo(subTitleLabel.snp.bottom).offset(10) + } + downloadStateButton.snp.makeConstraints { + $0.centerY.equalToSuperview() + $0.trailing.equalToSuperview().inset(20) + } + } + + func configure(app: App) { + titleLabel.text = app.title + iconImageView.image = app.iconImage + rankingLabel.text = "\(app.ranking)" + titleLabel.text = app.title + subTitleLabel.text = app.subtitle + categoryLabel.text = app.category + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Controller/FinanceChartViewController.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Controller/FinanceChartViewController.swift new file mode 100644 index 0000000..50bc61b --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Controller/FinanceChartViewController.swift @@ -0,0 +1,87 @@ +// +// FinanceChartViewController.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 11/1/24. +// + +import SnapKit +import UIKit +import Then + +class FinanceChartViewController: UIViewController { + + private let financeChartTableView = UITableView() + private let sectionList = FinanceSection.sectionData + private let appList = App.mockData + private let headerView = HeaderView() + + override func viewDidLoad() { + super.viewDidLoad() + + setUI() + setStyle() + setLayout() + } + + private func setUI() { + self.view.addSubview(financeChartTableView) + } + private func setStyle() { + financeChartTableView.do { + $0.register( + ChartCell.self, + forCellReuseIdentifier: ChartCell.identifier + ) + $0.register(HeaderView.self, forHeaderFooterViewReuseIdentifier: HeaderView.identifier) + $0.rowHeight = 100 + $0.delegate = self + $0.dataSource = self + } + } + private func setLayout() { + financeChartTableView.snp.makeConstraints { + $0.leading.trailing.top.bottom.equalToSuperview() + } + } +} + +extension FinanceChartViewController: UITableViewDelegate, UITableViewDataSource { + // MARK: - Section + func numberOfSections(in tableView: UITableView) -> Int { + return 4 + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: HeaderView.identifier) as? HeaderView else { + return nil + } + headerView.configure(section: sectionList[section]) + //headerView.backgroundColor = .cyan + return headerView + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + let sectionData = sectionList[section] + let headerHeight: CGFloat = sectionData.title.isEmpty ? 0 : + sectionData.subtitle.isEmpty ? 60 : 75 + return headerHeight + } + + // MARK: - Rows of Cells + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 4 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = financeChartTableView.dequeueReusableCell( + withIdentifier: ChartCell.identifier, + for: indexPath + ) as? ChartCell else { + return UITableViewCell() + } + cell.configure(app: appList[indexPath.row]) + return cell + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Model/FinanceSection.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Model/FinanceSection.swift new file mode 100644 index 0000000..f3a43ba --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/Model/FinanceSection.swift @@ -0,0 +1,39 @@ +// +// FinanceSection.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 11/1/24. +// + +import Foundation + +struct FinanceSection { + let title: String + let subtitle: String + let showAllButton: Bool +} + +extension FinanceSection { + static let sectionData: [FinanceSection] = [ + FinanceSection( + title: "", + subtitle: "", + showAllButton: false + ), + FinanceSection( + title: "필수 금융 앱", + subtitle: "App Store 에디터가 직접 골랐습니다", + showAllButton: true + ), + FinanceSection( + title: "유료 순위", + subtitle: "", + showAllButton: true + ), + FinanceSection( + title: "무료 순위", + subtitle: "", + showAllButton: true + ) + ] +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/View/HeaderView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/View/HeaderView.swift new file mode 100644 index 0000000..3910112 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/FinanceChart/View/HeaderView.swift @@ -0,0 +1,79 @@ +// +// HeaderView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 11/1/24. +// + +import SnapKit +import UIKit +import Then + +public class HeaderView: UITableViewHeaderFooterView { + let view = UIView() + let titleLabel = UILabel() + let subtitleLabel = UILabel() + let showAllButton = UIButton() + + static let identifier = "FinanceChartHeader" + + override init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + + setUp() + setStyle() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + addSubview(view) + [titleLabel, subtitleLabel, showAllButton].forEach { + view.addSubview($0) + } + } + + private func setStyle() { + titleLabel.do { + $0.font = .systemFont(ofSize: 20) + $0.textColor = .label + } + subtitleLabel.do { + $0.font = .systemFont(ofSize: 16) + $0.textColor = .secondaryLabel + } + showAllButton.do { + $0.setTitle("모두 보기", for: .normal) + $0.titleLabel?.font = .systemFont(ofSize: 16) + $0.setTitleColor(tintColor, for: .normal) + } + } + + private func setLayout() { + view.snp.makeConstraints { + $0.top.leading.trailing.bottom.equalToSuperview() + } + titleLabel.snp.makeConstraints { + $0.leading.equalToSuperview().inset(20) + $0.top.equalToSuperview().inset(20) + } + subtitleLabel.snp.makeConstraints { + $0.leading.equalToSuperview().inset(20) + $0.top.equalTo(titleLabel.snp.bottom).offset(5) + } + showAllButton.snp.makeConstraints { + $0.trailing.equalToSuperview().inset(20) + $0.top.equalToSuperview().inset(20) + } + } + + func configure(section: FinanceSection) { + titleLabel.text = section.title + subtitleLabel.text = section.subtitle + showAllButton.isHidden = !section.showAllButton + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/.DS_Store b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/.DS_Store new file mode 100644 index 0000000..c31818f Binary files /dev/null and b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/.DS_Store differ diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/AllReviewViewController.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/AllReviewViewController.swift new file mode 100644 index 0000000..2ea08a4 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/AllReviewViewController.swift @@ -0,0 +1,20 @@ +// +// AllReviewViewController.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import UIKit + +class AllReviewViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + } + + private func setStyle() { + self.view.backgroundColor = .systemBackground + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/TossViewController.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/TossViewController.swift new file mode 100644 index 0000000..378bd5d --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/TossViewController.swift @@ -0,0 +1,125 @@ +// +// ViewController.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/12/24. +// + +import UIKit +import SnapKit + +class TossViewController: UIViewController { + + private let scrollView = UIScrollView().then { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.backgroundColor = .systemBackground + $0.showsVerticalScrollIndicator = true + } + + private var contentView = UIView().then { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.backgroundColor = .systemBackground + } + + private let lineView = UIView().then { + $0.backgroundColor = .secondarySystemFill + } + + private let titleView = TitleView() + private let subTitleView = SubTitleView() + private let versionInfoView = VersionInfoView() + private let previewView = PreviewView() + private let ownerView = OwnerView() + private let appScoreView = AppScoreView() + private let reviewView = ReviewView() + + override func viewDidLoad() { + super.viewDidLoad() + + setStyle() + setUI() + setLayout() + setUpButton() + } + + private func setStyle() { + self.view.backgroundColor = .systemBackground + } + + private func setUI() { + self.view.addSubview(scrollView) + scrollView.addSubview(contentView) + [titleView, subTitleView, versionInfoView, previewView, ownerView, appScoreView, reviewView].forEach { contentView.addSubview($0) } + } + + private func setLayout() { + scrollView.snp.makeConstraints { + $0.top.equalToSuperview() + $0.bottom.equalToSuperview() + $0.leading.equalToSuperview() + $0.trailing.equalToSuperview() + } + contentView.snp.makeConstraints { + $0.edges.equalToSuperview() + $0.width.equalTo(scrollView.snp.width) + $0.height.equalTo(1550) + } + titleView.snp.makeConstraints { + $0.height.equalTo(150) + $0.leading.trailing.equalToSuperview() + $0.top.equalToSuperview() + } + subTitleView.snp.makeConstraints { + $0.height.equalTo(100) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(titleView.snp.bottom) + } + versionInfoView.snp.makeConstraints { + $0.height.equalTo(150) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(subTitleView.snp.bottom) + } + previewView.snp.makeConstraints { + $0.height.equalTo(500) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(versionInfoView.snp.bottom) + } + ownerView.snp.makeConstraints { + $0.height.equalTo(100) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(previewView + .snp.bottom) + } + appScoreView.snp.makeConstraints { + $0.height.equalTo(150) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(ownerView.snp.bottom) + } + reviewView.snp.makeConstraints { + $0.height.equalTo(500) + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(appScoreView.snp.bottom) + } + + } + + private func setUpButton() { + versionInfoView.updateRecordButton.addTarget(self, action: #selector(updateRecordButtonTapped), for: .touchUpInside) + + appScoreView.allReviewButton.addTarget(self, action: #selector(allReviewButtonTapped), for: .touchUpInside) + } +} + +extension TossViewController { + @objc private func updateRecordButtonTapped() { + print("updateRecordButtonTapped") + let nextVC = UpdateRecordViewController() + navigationController?.pushViewController(nextVC, animated: true) + } + + @objc private func allReviewButtonTapped() { + print("allReviewButtonTapped") + let nextVC = AllReviewViewController() + navigationController?.pushViewController(nextVC, animated: true) + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/UpdateRecordViewController.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/UpdateRecordViewController.swift new file mode 100644 index 0000000..54ec340 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/Controller/UpdateRecordViewController.swift @@ -0,0 +1,20 @@ +// +// UpdateRecordViewController.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import UIKit + +class UpdateRecordViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + } + + private func setStyle() { + self.view.backgroundColor = .systemBackground + } +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/AppScoreView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/AppScoreView.swift new file mode 100644 index 0000000..fff333f --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/AppScoreView.swift @@ -0,0 +1,73 @@ +// +// AppScoreView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +final class AppScoreView: UIView { + + private let titleLabel = UILabel().then { + $0.text = "평가 및 리뷰" + $0.font = .systemFont(ofSize: 24, weight: .bold) + $0.textColor = .label + $0.textAlignment = .left + } + private let scoreLabel = UILabel().then { + $0.text = "4.4" + $0.font = .systemFont(ofSize: 40, weight: .heavy) + $0.textColor = .label + $0.textAlignment = .center + } + private let baseScoreLabel = UILabel().then { + $0.text = "5점 만점" + $0.font = .systemFont(ofSize: 16) + $0.textColor = .secondaryLabel + $0.textAlignment = .center + } + public lazy var allReviewButton = UIButton().then { + $0.setTitle("모두 보기", for: .normal) + $0.backgroundColor = .systemBackground + $0.setTitleColor(.tintColor, for: .normal) + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + [titleLabel, scoreLabel, baseScoreLabel, baseScoreLabel, allReviewButton].forEach { + self.addSubview($0) + } + } + + private func setLayout() { + titleLabel.snp.makeConstraints { + $0.top.equalToSuperview().offset(20) + $0.leading.equalToSuperview().offset(20) + } + scoreLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(5) + $0.centerX.equalTo(titleLabel) + } + baseScoreLabel.snp.makeConstraints { + $0.top.equalTo(scoreLabel.snp.bottom).offset(5) + $0.centerX.equalTo(titleLabel) + } + allReviewButton.snp.makeConstraints { + $0.top.trailing.equalToSuperview().inset(20) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/HorizonView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/HorizonView.swift new file mode 100644 index 0000000..3c2a9db --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/HorizonView.swift @@ -0,0 +1,40 @@ +// +// HorizonView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +private class HorizonView: UIView { + + private let lineView = UIView().then { + $0.backgroundColor = .secondarySystemFill + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUp() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + addSubview(lineView) + } + + private func setLayout() { + lineView.snp.makeConstraints { + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalTo(1) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/OwnerView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/OwnerView.swift new file mode 100644 index 0000000..5b36ba6 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/OwnerView.swift @@ -0,0 +1,65 @@ +// +// DeveloperView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +final class OwnerView: UIView { + + private let ownerNameLabel = UILabel().then { + $0.text = "hee" + $0.textColor = .tintColor + $0.textAlignment = .left + $0.font = .systemFont(ofSize: 16, weight: .medium) + } + private let ownerJobLabel = UILabel().then { + $0.text = "개발자" + $0.textColor = .secondaryLabel + $0.textAlignment = .left + $0.font = .systemFont(ofSize: 14, weight: .medium) + } + private lazy var moreInfoImageView = UIImageView().then { + $0.image = UIImage(systemName: "chevron.right") + $0.tintColor = .secondaryLabel + $0.contentMode = .scaleAspectFit + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + [ownerNameLabel, ownerJobLabel, moreInfoImageView].forEach { + self.addSubview($0) + } + } + + private func setLayout() { + ownerNameLabel.snp.makeConstraints { + $0.top.leading.equalToSuperview().offset(20) + } + ownerJobLabel.snp.makeConstraints { + $0.top.equalTo(ownerNameLabel.snp.bottom) + $0.leading.equalToSuperview().offset(20) + } + moreInfoImageView.snp.makeConstraints { + $0.top.equalTo(ownerNameLabel.snp.top) + $0.trailing.equalToSuperview().inset(20) + $0.height.width.equalTo(30) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/PreviewView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/PreviewView.swift new file mode 100644 index 0000000..dde7e55 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/PreviewView.swift @@ -0,0 +1,55 @@ +// +// PreviewView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +final class PreviewView: UIView { + + private let titleLabel = UILabel().then { + $0.text = "미리보기" + $0.font = .systemFont(ofSize: 24, weight: .bold) + $0.textColor = .label + $0.textAlignment = .left + } + private lazy var preViewImageView = UIImageView().then { + $0.image = UIImage(named: "preview") + $0.contentMode = .scaleToFill + $0.clipsToBounds = true + $0.layer.cornerRadius = 10 + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + + private func setUI() { + addSubview(titleLabel) + addSubview(preViewImageView) + } + + private func setLayout() { + titleLabel.snp.makeConstraints { + $0.top.leading.trailing.equalToSuperview().inset(20) + } + preViewImageView.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(10) + $0.leading.trailing.bottom.equalToSuperview().inset(20) + $0.height.equalTo(400) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/ReviewView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/ReviewView.swift new file mode 100644 index 0000000..e6fd847 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/ReviewView.swift @@ -0,0 +1,134 @@ +// +// ReviewView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +final class ReviewView: UIView { + + private let gettingReviewLabel = UILabel().then { + $0.text = "탭하여 평가하기:" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.textColor = .secondaryLabel + $0.textAlignment = .left + } + private let reviewView = UIView().then { + $0.backgroundColor = .tertiarySystemFill + $0.clipsToBounds = true + $0.layer.cornerRadius = 10 + } + private let reviewTitleLabel = UILabel().then { + $0.text = "토스 UX 전 버전" + $0.font = .systemFont(ofSize: 16, weight: .bold) + $0.textColor = .label + } + private let reviewDateLabel = UILabel().then { + $0.text = "9월 27일" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.textColor = .secondaryLabel + } + private let reviewUserLabel = UILabel().then { + $0.text = "개발자 아님ㅠㅠ" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.textColor = .secondaryLabel + } + private let reviewContextLabel = UILabel().then { + $0.text = "최근 업데이트가 토스만의 UX색깔 개성 자체를 잃어버린 것 같습니다. 메인 화면 뜰 때마다 되게 부드럽고 한 눈에 보기 편했는데, 이번 업데이트로 인해 토스만의" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.numberOfLines = 0 + $0.textColor = .label + } + private let answerTitleLabel = UILabel().then { + $0.text = "개발자 답변" + $0.font = .systemFont(ofSize: 16, weight: .bold) + $0.textColor = .label + } + private let answerDateLabel = UILabel().then { + $0.text = "9월 29일" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.textColor = .secondaryLabel + } + private let answerContextLabel = UILabel().then { + $0.text = "안녕하세요. 토스팀입니다. 소중한 의견을 주셔서 너무나 감사합니다. 토스화면 UI를 사용자의 사용에" + $0.font = .systemFont(ofSize: 16, weight: .medium) + $0.numberOfLines = 0 + $0.textColor = .label + } + public lazy var makeReviewButton = UIButton().then { + $0.setTitle("리뷰 작성", for: .normal) + $0.backgroundColor = .systemBackground + $0.setImage(UIImage(systemName: "square.and.pencil"), for: .normal) + $0.tintColor = .systemBlue + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + [gettingReviewLabel, reviewView, makeReviewButton].forEach { + self.addSubview($0) + } + [reviewTitleLabel, reviewDateLabel, reviewUserLabel, reviewContextLabel, answerTitleLabel, answerDateLabel, answerContextLabel].forEach { + reviewView.addSubview($0) + } + } + + private func setLayout() { + gettingReviewLabel.snp.makeConstraints { + $0.top.leading.equalToSuperview().offset(20) + } + reviewView.snp.makeConstraints { + $0.top.equalTo(gettingReviewLabel.snp.bottom).offset(20) + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalTo(280) + } + makeReviewButton.snp.makeConstraints { + $0.top.equalTo(reviewView.snp.bottom).offset(20) + $0.leading.equalToSuperview().inset(20) + $0.height.equalTo(30) + } + reviewTitleLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(20) + $0.leading.equalToSuperview().inset(20) + } + reviewDateLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(20) + $0.trailing.equalToSuperview().inset(20) + } + reviewUserLabel.snp.makeConstraints { + $0.top.equalTo(reviewDateLabel.snp.bottom).offset(10) + $0.trailing.equalToSuperview().inset(20) + } + reviewContextLabel.snp.makeConstraints { + $0.top.equalTo(reviewUserLabel.snp.bottom).offset(10) + $0.leading.trailing.equalToSuperview().inset(20) + } + + answerTitleLabel.snp.makeConstraints { + $0.top.equalTo(reviewContextLabel.snp.bottom).offset(20) + $0.leading.equalToSuperview().inset(20) + } + answerDateLabel.snp.makeConstraints { + $0.top.equalTo(answerTitleLabel.snp.top) + $0.trailing.equalToSuperview().inset(20) + } + answerContextLabel.snp.makeConstraints { + $0.top.equalTo(answerDateLabel.snp.bottom).offset(10) + $0.leading.trailing.equalToSuperview().inset(20) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/SubTitleView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/SubTitleView.swift new file mode 100644 index 0000000..c9c928d --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/SubTitleView.swift @@ -0,0 +1,72 @@ +// +// SubTitleView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import Then +import UIKit + +final class SubTitleView: UIView { + + private let examView = UIView().then { + $0.backgroundColor = .systemBackground + } + private let titleLabel = UILabel().then { + $0.text = "임시" + $0.font = .systemFont(ofSize: 14, weight: .medium) + $0.textColor = .secondaryLabel + } + private let numberLabel = UILabel().then { + $0.text = "임시" + $0.font = .systemFont(ofSize: 25, weight: .bold) + $0.textColor = .secondaryLabel + } + private let bottomLabel = UILabel().then { + $0.text = "임시" + $0.font = .systemFont(ofSize: 14, weight: .medium) + $0.textColor = .secondaryLabel + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + self.addSubview(examView) + [titleLabel, numberLabel, bottomLabel].forEach { + examView.addSubview($0) + } + } + + private func setLayout() { + examView.snp.makeConstraints { + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalToSuperview() + } + + titleLabel.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.bottom.equalTo(numberLabel.snp.top).offset(-5) + } + + numberLabel.snp.makeConstraints { + $0.centerX.centerY.equalToSuperview() + } + + bottomLabel.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.top.equalTo(numberLabel.snp.bottom).offset(5) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/TitleView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/TitleView.swift new file mode 100644 index 0000000..89f3173 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/TitleView.swift @@ -0,0 +1,87 @@ +// +// TitleView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import Then +import UIKit + +class TitleView: UIView { + + private let appIconImageView = UIImageView().then { + $0.image = UIImage(named: "icon_toss") + $0.layer.cornerRadius = 25 + $0.clipsToBounds = true + } + private let titleLabel = UILabel().then { + $0.text = "토스" + $0.textAlignment = .left + $0.textColor = .label + $0.font = .systemFont(ofSize: 20) + } + private let subTitleLabel = UILabel().then { + $0.text = "금융이 쉬워진다" + $0.textAlignment = .left + $0.textColor = .secondaryLabel + $0.font = .systemFont(ofSize: 15) + } + public lazy var installButton = UIButton().then { + $0.setTitle("받기", for: .normal) // bold 처리 해야함. + $0.setTitleColor(.white, for: .normal) + $0.backgroundColor = .systemBlue + $0.layer.cornerRadius = 15 + } + public lazy var shareButton = UIButton().then { + $0.setImage(UIImage(systemName: "square.and.arrow.up"), for: .normal) + $0.tintColor = .systemBlue + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + [appIconImageView, titleLabel, subTitleLabel, installButton, shareButton].forEach { + self.addSubview($0) + } + } + + private func setLayout() { + appIconImageView.snp.makeConstraints { + $0.leading.equalToSuperview().inset(20) + $0.top.bottom.equalToSuperview().inset(20) + $0.width.equalTo(appIconImageView.snp.height) + } + titleLabel.snp.makeConstraints { + $0.leading.equalTo(appIconImageView.snp.trailing).offset(20) + $0.trailing.equalToSuperview().inset(20) + $0.top.equalToSuperview().inset(20) + } + subTitleLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(5) + $0.leading.trailing.equalTo(titleLabel) + } + installButton.snp.makeConstraints { + $0.bottom.equalToSuperview().inset(20) + $0.leading.equalTo(titleLabel) + $0.height.equalTo(30) + $0.width.equalTo(80) + } + shareButton.snp.makeConstraints { + $0.trailing.equalToSuperview().inset(20) + $0.bottom.equalTo(installButton.snp.bottom) + $0.width.height.equalTo(30) + } + } + +} diff --git a/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/VersionInfoView.swift b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/VersionInfoView.swift new file mode 100644 index 0000000..e49ef99 --- /dev/null +++ b/35-Seminar-hee2/35-Seminar-hee2/Source/Toss/View/VersionInfoView.swift @@ -0,0 +1,86 @@ +// +// VersionInfoView.swift +// 35-Seminar-hee2 +// +// Created by 김희은 on 10/25/24. +// + +import SnapKit +import UIKit +import Then + +final class VersionInfoView: UIView { + + private let titleLabel = UILabel().then { + $0.text = "새로운 소식" + $0.font = .systemFont(ofSize: 24, weight: .bold) + $0.textColor = .label + $0.textAlignment = .left + } + private let versionLabel = UILabel().then { + $0.text = "버전 5.183.0" + $0.font = .systemFont(ofSize: 14) + $0.textColor = .secondaryLabel + $0.textAlignment = .left + } + public lazy var updateRecordButton = UIButton().then { + $0.setTitle("버전 기록", for: .normal) + $0.backgroundColor = .systemBackground + $0.setTitleColor(.tintColor, for: .normal) + } + private let updateDateLabel = UILabel().then { + $0.text = "2024.10.25" + $0.font = .systemFont(ofSize: 14) + $0.textColor = .secondaryLabel + $0.textAlignment = .left + } + private let contextLabel = UILabel().then { + $0.text = "- 구석구석 숨어있던 버그들을 잡았어요. 또 다른 버그가 나타나면 토스 고객센터를 찾아주세요. 늘 열여있답니다. 365일 24시간 언제든지요." + $0.font = .systemFont(ofSize: 14) + $0.textColor = .label + $0.textAlignment = .left + $0.numberOfLines = 0 + } + + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUI() { + [titleLabel, versionLabel, updateRecordButton, updateDateLabel, contextLabel].forEach { + self.addSubview($0) + } + } + + private func setLayout() { + titleLabel.snp.makeConstraints { + $0.top.equalToSuperview().offset(5) + $0.leading.equalToSuperview().offset(20) + } + versionLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(5) + $0.leading.equalToSuperview().inset(20) + } + contextLabel.snp.makeConstraints { + $0.top.equalTo(versionLabel.snp.bottom).offset(10) + $0.leading.trailing.bottom.equalToSuperview().inset(20) + } + updateRecordButton.snp.makeConstraints { + $0.trailing.equalToSuperview().inset(20) + $0.top.equalToSuperview().offset(5) + $0.height.equalTo(titleLabel.snp.height) + } + updateDateLabel.snp.makeConstraints { + $0.top.equalTo(updateRecordButton.snp.bottom).offset(5) + $0.trailing.equalToSuperview().inset(20) + } + } + +}