diff --git a/iOS_Study_B.xcodeproj/project.pbxproj b/iOS_Study_B.xcodeproj/project.pbxproj index 9763af9..500470e 100644 --- a/iOS_Study_B.xcodeproj/project.pbxproj +++ b/iOS_Study_B.xcodeproj/project.pbxproj @@ -7,20 +7,28 @@ objects = { /* Begin PBXBuildFile section */ + 2D55A19F2B04DE94005EDF94 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2D55A19E2B04DE94005EDF94 /* SnapKit */; }; + 2D55A1A12B04DE94005EDF94 /* SnapKit-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 2D55A1A02B04DE94005EDF94 /* SnapKit-Dynamic */; }; + 2D55A1A32B04E143005EDF94 /* MemoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D55A1A22B04E143005EDF94 /* MemoTableViewCell.swift */; }; + 2D55A1A52B04E699005EDF94 /* AddMemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D55A1A42B04E699005EDF94 /* AddMemoViewController.swift */; }; + 2DE266212B0B1AC0006E53CE /* DetailMemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE266202B0B1AC0006E53CE /* DetailMemoViewController.swift */; }; + 2DE266232B0B333A006E53CE /* EditMemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE266222B0B333A006E53CE /* EditMemoViewController.swift */; }; 954B6B812AC57DAA00FDCFAB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */; }; 954B6B832AC57DAA00FDCFAB /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */; }; - 954B6B852AC57DAA00FDCFAB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B842AC57DAA00FDCFAB /* ViewController.swift */; }; - 954B6B882AC57DAA00FDCFAB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B862AC57DAA00FDCFAB /* Main.storyboard */; }; + 954B6B852AC57DAA00FDCFAB /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B842AC57DAA00FDCFAB /* MainViewController.swift */; }; 954B6B8A2AC57DAB00FDCFAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */; }; 954B6B8D2AC57DAB00FDCFAB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2D55A1A22B04E143005EDF94 /* MemoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoTableViewCell.swift; sourceTree = ""; }; + 2D55A1A42B04E699005EDF94 /* AddMemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMemoViewController.swift; sourceTree = ""; }; + 2DE266202B0B1AC0006E53CE /* DetailMemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailMemoViewController.swift; sourceTree = ""; }; + 2DE266222B0B333A006E53CE /* EditMemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMemoViewController.swift; sourceTree = ""; }; 954B6B7D2AC57DAA00FDCFAB /* iOS_Study_B.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOS_Study_B.app; sourceTree = BUILT_PRODUCTS_DIR; }; 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 954B6B842AC57DAA00FDCFAB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 954B6B872AC57DAA00FDCFAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 954B6B842AC57DAA00FDCFAB /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 954B6B8C2AC57DAB00FDCFAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 954B6B8E2AC57DAB00FDCFAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -31,6 +39,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2D55A19F2B04DE94005EDF94 /* SnapKit in Frameworks */, + 2D55A1A12B04DE94005EDF94 /* SnapKit-Dynamic in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -58,8 +68,11 @@ children = ( 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */, 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */, - 954B6B842AC57DAA00FDCFAB /* ViewController.swift */, - 954B6B862AC57DAA00FDCFAB /* Main.storyboard */, + 954B6B842AC57DAA00FDCFAB /* MainViewController.swift */, + 2D55A1A42B04E699005EDF94 /* AddMemoViewController.swift */, + 2D55A1A22B04E143005EDF94 /* MemoTableViewCell.swift */, + 2DE266202B0B1AC0006E53CE /* DetailMemoViewController.swift */, + 2DE266222B0B333A006E53CE /* EditMemoViewController.swift */, 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */, 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */, 954B6B8E2AC57DAB00FDCFAB /* Info.plist */, @@ -83,6 +96,10 @@ dependencies = ( ); name = iOS_Study_B; + packageProductDependencies = ( + 2D55A19E2B04DE94005EDF94 /* SnapKit */, + 2D55A1A02B04DE94005EDF94 /* SnapKit-Dynamic */, + ); productName = iOS_Study_B; productReference = 954B6B7D2AC57DAA00FDCFAB /* iOS_Study_B.app */; productType = "com.apple.product-type.application"; @@ -111,6 +128,9 @@ Base, ); mainGroup = 954B6B742AC57DAA00FDCFAB; + packageReferences = ( + 2D55A19D2B04DE94005EDF94 /* XCRemoteSwiftPackageReference "SnapKit" */, + ); productRefGroup = 954B6B7E2AC57DAA00FDCFAB /* Products */; projectDirPath = ""; projectRoot = ""; @@ -127,7 +147,6 @@ files = ( 954B6B8D2AC57DAB00FDCFAB /* LaunchScreen.storyboard in Resources */, 954B6B8A2AC57DAB00FDCFAB /* Assets.xcassets in Resources */, - 954B6B882AC57DAA00FDCFAB /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -138,23 +157,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 954B6B852AC57DAA00FDCFAB /* ViewController.swift in Sources */, + 954B6B852AC57DAA00FDCFAB /* MainViewController.swift in Sources */, + 2DE266232B0B333A006E53CE /* EditMemoViewController.swift in Sources */, + 2D55A1A52B04E699005EDF94 /* AddMemoViewController.swift in Sources */, 954B6B812AC57DAA00FDCFAB /* AppDelegate.swift in Sources */, 954B6B832AC57DAA00FDCFAB /* SceneDelegate.swift in Sources */, + 2D55A1A32B04E143005EDF94 /* MemoTableViewCell.swift in Sources */, + 2DE266212B0B1AC0006E53CE /* DetailMemoViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 954B6B862AC57DAA00FDCFAB /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 954B6B872AC57DAA00FDCFAB /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -291,7 +306,6 @@ INFOPLIST_FILE = iOS_Study_B/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -318,7 +332,6 @@ INFOPLIST_FILE = iOS_Study_B/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -356,6 +369,30 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 2D55A19D2B04DE94005EDF94 /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.6.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 2D55A19E2B04DE94005EDF94 /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 2D55A19D2B04DE94005EDF94 /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + 2D55A1A02B04DE94005EDF94 /* SnapKit-Dynamic */ = { + isa = XCSwiftPackageProductDependency; + package = 2D55A19D2B04DE94005EDF94 /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = "SnapKit-Dynamic"; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 954B6B752AC57DAA00FDCFAB /* Project object */; } diff --git a/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..009c162 --- /dev/null +++ b/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "f222cbdf325885926566172f6f5f06af95473158", + "version" : "5.6.0" + } + } + ], + "version" : 2 +} diff --git a/iOS_Study_B/AddMemoViewController.swift b/iOS_Study_B/AddMemoViewController.swift new file mode 100644 index 0000000..22750ed --- /dev/null +++ b/iOS_Study_B/AddMemoViewController.swift @@ -0,0 +1,79 @@ +// +// AddMemoViewController.swift +// iOS_Study_B +// +// Created by 정민지 on 11/15/23. +// + +import UIKit +import SnapKit + +struct MemoInformation: Identifiable { + var id: ObjectIdentifier? + var title: String? + var content: String? +} + +class AddMemoViewController: UIViewController { + let TitleTextField: UITextField = { + let textField = UITextField() + textField.placeholder = "제목 입력" + textField.borderStyle = .roundedRect + return textField + }() + let ContentTextField: UITextField = { + let textField = UITextField() + textField.placeholder = "내용 입력" + textField.borderStyle = .roundedRect + return textField + }() + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + + configureSubviews() + makeConstraints() + + navigationItem.title = "메모 작성" + setNavigationBar() + } + + func configureSubviews() { + view.addSubview(TitleTextField) + view.addSubview(ContentTextField) + + } + + func makeConstraints() { + TitleTextField.snp.makeConstraints{make in + make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + ContentTextField.snp.makeConstraints{make in + make.top.equalTo(TitleTextField.snp.bottom).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + } + + func setNavigationBar() { + let addButton = UIBarButtonItem(title: "작성하기" , style: .plain, target: self, action: #selector(addButtonTapped)) + navigationItem.rightBarButtonItem = addButton + } + @objc func addButtonTapped() { + guard let title = TitleTextField.text, let content = ContentTextField.text else { + // 제목 또는 내용이 nil일 경우 처리 + return + } + + // 입력된 값으로 Memo 객체 생성 + let newMemo = MemoInformation(id: ObjectIdentifier(self), title: title, content: content) + + // ViewController에 대한 참조를 가져와 새로운 메모를 추가 + if let viewController = navigationController?.viewControllers.first as? MainViewController { + viewController.addMemo(newMemo) + } + + self.navigationController?.popViewController(animated: true) + } +} diff --git a/iOS_Study_B/Base.lproj/Main.storyboard b/iOS_Study_B/Base.lproj/Main.storyboard deleted file mode 100644 index 25a7638..0000000 --- a/iOS_Study_B/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iOS_Study_B/DetailMemoViewController.swift b/iOS_Study_B/DetailMemoViewController.swift new file mode 100644 index 0000000..81cdbf0 --- /dev/null +++ b/iOS_Study_B/DetailMemoViewController.swift @@ -0,0 +1,127 @@ +// +// DetailMemoViewController.swift +// iOS_Study_B +// +// Created by 정민지 on 11/20/23. +// + +import UIKit +import SnapKit + +class DetailMemoViewController: UIViewController { + var memo: MemoInformation? + var index: Int? + weak var delegate: EditMemoDelegate? + + let TitleLabel: UILabel = { + let label = UILabel() + label.font = UIFont.boldSystemFont(ofSize: 18) + return label + }() + + let ContentLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 16) + label.numberOfLines = 0 + return label + }() + + + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + + configureSubviews() + makeConstraints() + + navigationItem.title = "메모 상세" + setNavigationBar() + + if let memo = memo { + displayMemoInformation(memo) + } + } + + //pop으로 화면이 사라질때 함수 호출 + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + if isMovingFromParent { + backButtonTapped() + } + } + + func configureSubviews() { + view.addSubview(TitleLabel) + view.addSubview(ContentLabel) + + } + + func makeConstraints() { + TitleLabel.snp.makeConstraints { make in + make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + ContentLabel.snp.makeConstraints { make in + make.top.equalTo(TitleLabel.snp.bottom).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + } + + // 네비게이션 바 "수정하기" 버튼 + func setNavigationBar() { + let editButton = UIBarButtonItem(title: "수정하기", style: .plain, target: self, action: #selector(editButtonTapped)) + navigationItem.rightBarButtonItem = editButton + } + + // "수정하기" 버튼 눌렀을때 동작 + @objc func editButtonTapped() { + let EditMemoViewController = EditMemoViewController() + + EditMemoViewController.memo = memo + EditMemoViewController.index = index + EditMemoViewController.delegate = self + self.navigationController?.pushViewController(EditMemoViewController, animated: true) + } + + //pop으로 화면이 사라질때 함수 호출 시 수행할 동작 + @objc func backButtonTapped() { + guard let updatedMemo = createUpdatedMemo() else { + return + } + + delegate?.didUpdateMemo(updatedMemo, atIndex: index!) + self.navigationController?.popViewController(animated: true) + } + + //Label에 있는 내용들 새로운 메모 데이터에 담고 리턴하는 함수 + func createUpdatedMemo() -> MemoInformation? { + guard let updatedTitle = TitleLabel.text, + let updatedContent = ContentLabel.text else { + return nil + } + + return MemoInformation(id: memo?.id, title: updatedTitle, content: updatedContent) + } + + //데이터 받아와서 기존의 Label내용 수정하는 함수 + func displayMemoInformation(_ memo: MemoInformation) { + TitleLabel.text = memo.title + ContentLabel.text = memo.content + } +} + +//데이터 전송시 필요한 애들 +protocol EditMemoDelegate: AnyObject { + func didUpdateMemo(_ memo: MemoInformation, atIndex: Int) +} + +extension DetailMemoViewController: EditMemoDelegate { + func didUpdateMemo(_ memo: MemoInformation, atIndex: Int) { + displayMemoInformation(memo) + } +} + + + diff --git a/iOS_Study_B/EditMemoViewController.swift b/iOS_Study_B/EditMemoViewController.swift new file mode 100644 index 0000000..596258d --- /dev/null +++ b/iOS_Study_B/EditMemoViewController.swift @@ -0,0 +1,87 @@ + +import UIKit +import SnapKit + +class EditMemoViewController: UIViewController { + var memo: MemoInformation? + var index: Int? + weak var delegate: EditMemoDelegate? + + let TitleTextField: UITextField = { + let textField = UITextField() + textField.borderStyle = .roundedRect + return textField + }() + let ContentTextField: UITextField = { + let textField = UITextField() + textField.borderStyle = .roundedRect + return textField + }() + + + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + + configureSubviews() + makeConstraints() + + navigationItem.title = "메모 수정" + setNavigationBar() + + if let memo = memo { + displayMemoInformation(memo) + } + + } + + func configureSubviews() { + view.addSubview(TitleTextField) + view.addSubview(ContentTextField) + + } + + func makeConstraints() { + TitleTextField.snp.makeConstraints { make in + make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + ContentTextField.snp.makeConstraints { make in + make.top.equalTo(TitleTextField.snp.bottom).offset(20) + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(20) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-20)} + } + + //네이게이션 바 "완료" 버튼 생성 + func setNavigationBar() { + let completeButton = UIBarButtonItem(title: "완료", style: .plain, target: self, action: #selector(completeButtonTapped)) + navigationItem.rightBarButtonItem = completeButton + } + + //"완료" 버튼 눌렀을때 수행하는 동작 + @objc func completeButtonTapped() { + guard let updatedMemo = createUpdatedMemo() else { + return + } + + delegate?.didUpdateMemo(updatedMemo, atIndex: index!) + self.navigationController?.popViewController(animated: true) + } + + //DetailMemoViewController로부터 받아온 데이터에 따라 TextField 수정 + func displayMemoInformation(_ memo: MemoInformation) { + TitleTextField.text = memo.title + ContentTextField.text = memo.content + } + + //TextField에서 수정된 내용을 가져와서 MemoInformation을 업데이트 + func createUpdatedMemo() -> MemoInformation? { + guard let updatedTitle = TitleTextField.text, + let updatedContent = ContentTextField.text else { + return nil + } + + return MemoInformation(id: memo?.id, title: updatedTitle, content: updatedContent) + } +} diff --git a/iOS_Study_B/Info.plist b/iOS_Study_B/Info.plist index dd3c9af..0eb786d 100644 --- a/iOS_Study_B/Info.plist +++ b/iOS_Study_B/Info.plist @@ -15,8 +15,6 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main diff --git a/iOS_Study_B/MainViewController.swift b/iOS_Study_B/MainViewController.swift new file mode 100644 index 0000000..e616d11 --- /dev/null +++ b/iOS_Study_B/MainViewController.swift @@ -0,0 +1,117 @@ +// +// ViewController.swift +// iOS_Study_B +// +// Created by 박지윤 on 2023/09/28. +// + +import UIKit +import SnapKit + +class MainViewController: UIViewController { + + var memos = [MemoInformation]() + + let tableView: UITableView = { + let tableView = UITableView() + tableView.backgroundColor = .white + tableView.register(MemoTableViewCell.self, forCellReuseIdentifier: MemoTableViewCell.identifier) + + return tableView + }() + + + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + + configureSubviews() + makeConstraints() + + tableView.dataSource = self + tableView.delegate = self + + navigationItem.title = "메모장" + setNavigationBar() + + } + + func configureSubviews() { + view.addSubview(tableView) + } + + func makeConstraints() { + tableView.snp.makeConstraints { make in + make.edges.equalTo(view.safeAreaLayoutGuide) + } + } + + //네비게이션 바 "+" 버튼 + func setNavigationBar() { + let addButton = UIBarButtonItem(image: UIImage(systemName: "plus"), style: .plain, target: self, action: #selector(addButtonTapped)) + navigationItem.rightBarButtonItem = addButton + } + + //"+" 버튼 눌렀을때 동작 + @objc func addButtonTapped() { + let addMemoViewController = AddMemoViewController() + self.navigationController?.pushViewController(addMemoViewController, animated: true) + } + + func addMemo(_ memo: MemoInformation) { + memos.append(memo) + tableView.reloadData() + } + + // tableView 삭제 동작 + func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { + let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (_, _, completionHandler) in + + self.memos.remove(at: indexPath.row) + tableView.deleteRows(at: [indexPath], with: .fade) + completionHandler(true) + } + + return UISwipeActionsConfiguration(actions: [deleteAction]) + } + + // tableView 상세 정보 창 넘어가기 + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let detailMemoViewController = DetailMemoViewController() + + detailMemoViewController.memo = memos[indexPath.row] + detailMemoViewController.index = indexPath.row + detailMemoViewController.delegate = self + + self.navigationController?.pushViewController(detailMemoViewController, animated: true) + } +} + + +//테이블 뷰에 테이블 뷰 셀 넣기 +extension MainViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return memos.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: MemoTableViewCell.identifier, for: indexPath) as? MemoTableViewCell else { return UITableViewCell() } + let memo = memos[indexPath.row] + + cell.configure(with: memo) + + return cell + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 80 + } +} + +//memo 데이터 전달 +extension MainViewController: EditMemoDelegate { + func didUpdateMemo(_ memo: MemoInformation, atIndex index: Int) { + memos[index] = memo + tableView.reloadData() + } +} diff --git a/iOS_Study_B/MemoTableViewCell.swift b/iOS_Study_B/MemoTableViewCell.swift new file mode 100644 index 0000000..7031b66 --- /dev/null +++ b/iOS_Study_B/MemoTableViewCell.swift @@ -0,0 +1,61 @@ +// +// MemoTableViewCell.swift +// iOS_Study_B +// +// Created by 정민지 on 11/15/23. +// + +import UIKit +import SnapKit + +class MemoTableViewCell: UITableViewCell { + static let identifier = "MemoTableViewCell" + + let TitleLabel: UILabel = { + let label = UILabel() + label.font = UIFont.boldSystemFont(ofSize: 23) + + return label + }() + let ContentLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 16) + label.numberOfLines = 1 + + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + configureSubviews() + makeConstraints() + } + + override func awakeFromNib() { + super.awakeFromNib() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configureSubviews() { + contentView.addSubview(TitleLabel) + contentView.addSubview(ContentLabel) + } + func makeConstraints() { + TitleLabel.snp.makeConstraints { make in + make.top.equalTo(contentView).inset(10) + make.leading.equalTo(contentView).inset(15) + } + + ContentLabel.snp.makeConstraints { make in + make.top.equalTo(TitleLabel.snp.bottom).offset(10) + make.leading.equalTo(contentView).inset(15) + } + } + func configure(with memo: MemoInformation) { + TitleLabel.text = memo.title + ContentLabel.text = memo.content + } +} diff --git a/iOS_Study_B/SceneDelegate.swift b/iOS_Study_B/SceneDelegate.swift index 9987c27..de466d0 100644 --- a/iOS_Study_B/SceneDelegate.swift +++ b/iOS_Study_B/SceneDelegate.swift @@ -13,10 +13,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } + guard let windowScene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowScene) + + let mainViewController = MainViewController() + let navigationController = UINavigationController(rootViewController: mainViewController) + + window?.rootViewController = navigationController + window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/iOS_Study_B/ViewController.swift b/iOS_Study_B/ViewController.swift deleted file mode 100644 index f3577b5..0000000 --- a/iOS_Study_B/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// iOS_Study_B -// -// Created by 박지윤 on 2023/09/28. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} -