diff --git a/README.md b/README.md index ed637fc..df820ee 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,45 @@ -## 프로젝트 번호 : 프로젝트 이름 - -간략한 설명 - -이 앱의 레퍼런스는 [soapyigu의 Swift-30-Projects Project 04 - TodoTDD](https://github.com/soapyigu/Swift-30-Projects/tree/master/Project%2004%20-%20TodoTDD)입니다. - -기본 기능을 모두 구현했다면, 디자인 및 추가 기능 구현은 자유롭게 해주세요. - -## 가이드 - -영상 가이드는 [코드스쿼드 pr연습](https://www.youtube.com/watch?v=lFinZfu3QO0)을 참조해주세요. - -1. 본인 이름으로 브랜치(ex: PAKA)를 생성한 후, 자신의 레포로 fork해주세요. - -2. fork 한 레포에서 기능 또는 화면 단위로 새 브랜치(ex: pr1)를 생성 후 작업 및 커밋합니다. - -3. 커밋했던 브랜치(pr1)에서 자신의 이름 브랜치(PAKA)로 PR을 올려주세요. - -4. 코드 리뷰를 받고 모든 수정사항을 반영한 후 `squash and merge` 옵션으로 자신의 브랜치에 merge해주세요. - -5. merge했던 브랜치(pr1)에서 fork한 레포의 main 브랜치로 checkout후 해당 브랜치(pr1)를 삭제합니다. - -6. 다음 명령어들을 순차적으로 실행합니다. - -``` - git remote add upstream https://github.com/Swift-Master/Project1-GoodAsOldPhones - - git fetch upstream `본인의 브랜치명(ex:PAKA)` - - git rebase upstream `upstream/본인의브랜치명(ex:PAKA)` +# Project4 : ToDoTDD + +## 20230608 + +### Main 화면 +- Navigation Item으로 Input 화면 이동 +- TableView + +### Input 화면 +- TextField, DatePicker + +## 20230609 + +### MVC 구조 변경 +```markdown +- Project + - Sources + - AppDelegate.swift + - SceneDelegate.swift + - Models + - ... + - Views + - ... + - Controllers + - ... + - Helpers + - ... + - Resources + - Assets.xcassets + - ... + - Supporting Files + - Info.plist + - ... + - Tests + - ... ``` +info.plist의 경우 루트 경로가 지정되어 있어서 Build Setting에서 경로를 변경해주어야 됨 -7. 2번으로 돌아가 새로운 작업을 반복합니다. +### Detail 화면 +- `import MapKit` +- 입력한 주소를 지도 가운데로 이동 +- Annotation을 사용하여 이동한 주소에 핀을 꽂고, 설명 출력 -## 실제 화면 -![시뮬레이터화면](./ToDoTDD.gif) +## 구현 화면 + diff --git a/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.pbxproj b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.pbxproj index d58978a..1cd5cad 100644 --- a/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.pbxproj +++ b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.pbxproj @@ -7,9 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + 653CF0802A31998200581290 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653CF07F2A31998200581290 /* Model.swift */; }; + 653CF0822A319A3500581290 /* InputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653CF0812A319A3500581290 /* InputViewController.swift */; }; + 653CF0842A31BB2600581290 /* MainTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653CF0832A31BB2600581290 /* MainTableViewCell.swift */; }; + 653CF08D2A32C2B400581290 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653CF08C2A32C2B400581290 /* DetailViewController.swift */; }; 6E52A5502A2108FD009A81D2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E52A54F2A2108FD009A81D2 /* AppDelegate.swift */; }; 6E52A5522A2108FD009A81D2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E52A5512A2108FD009A81D2 /* SceneDelegate.swift */; }; - 6E52A5542A2108FD009A81D2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E52A5532A2108FD009A81D2 /* ViewController.swift */; }; + 6E52A5542A2108FD009A81D2 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E52A5532A2108FD009A81D2 /* MainViewController.swift */; }; 6E52A5572A2108FD009A81D2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E52A5552A2108FD009A81D2 /* Main.storyboard */; }; 6E52A5592A2108FE009A81D2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6E52A5582A2108FE009A81D2 /* Assets.xcassets */; }; 6E52A55C2A2108FE009A81D2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E52A55A2A2108FE009A81D2 /* LaunchScreen.storyboard */; }; @@ -36,10 +40,14 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 653CF07F2A31998200581290 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; + 653CF0812A319A3500581290 /* InputViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputViewController.swift; sourceTree = ""; }; + 653CF0832A31BB2600581290 /* MainTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTableViewCell.swift; sourceTree = ""; }; + 653CF08C2A32C2B400581290 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; 6E52A54C2A2108FD009A81D2 /* ToDoListOfTDD.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ToDoListOfTDD.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6E52A54F2A2108FD009A81D2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 6E52A5512A2108FD009A81D2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 6E52A5532A2108FD009A81D2 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 6E52A5532A2108FD009A81D2 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 6E52A5562A2108FD009A81D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 6E52A5582A2108FE009A81D2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 6E52A55B2A2108FE009A81D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; @@ -76,6 +84,62 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 653CF0852A32B9F800581290 /* Sources */ = { + isa = PBXGroup; + children = ( + 653CF08A2A32BA4B00581290 /* Controllers */, + 653CF0892A32BA4300581290 /* Views */, + 653CF0882A32BA3C00581290 /* Models */, + 6E52A5512A2108FD009A81D2 /* SceneDelegate.swift */, + 6E52A54F2A2108FD009A81D2 /* AppDelegate.swift */, + ); + path = Sources; + sourceTree = ""; + }; + 653CF0862A32BA0900581290 /* Resources */ = { + isa = PBXGroup; + children = ( + 6E52A5582A2108FE009A81D2 /* Assets.xcassets */, + ); + path = Resources; + sourceTree = ""; + }; + 653CF0872A32BA1A00581290 /* SupportingFiles */ = { + isa = PBXGroup; + children = ( + 6E52A55D2A2108FE009A81D2 /* Info.plist */, + ); + path = SupportingFiles; + sourceTree = ""; + }; + 653CF0882A32BA3C00581290 /* Models */ = { + isa = PBXGroup; + children = ( + 653CF07F2A31998200581290 /* Model.swift */, + ); + path = Models; + sourceTree = ""; + }; + 653CF0892A32BA4300581290 /* Views */ = { + isa = PBXGroup; + children = ( + 653CF0832A31BB2600581290 /* MainTableViewCell.swift */, + 6E52A55A2A2108FE009A81D2 /* LaunchScreen.storyboard */, + 6E52A5552A2108FD009A81D2 /* Main.storyboard */, + ); + path = Views; + sourceTree = ""; + }; + 653CF08A2A32BA4B00581290 /* Controllers */ = { + isa = PBXGroup; + children = ( + 6E52A5532A2108FD009A81D2 /* MainViewController.swift */, + 653CF0812A319A3500581290 /* InputViewController.swift */, + 653CF08C2A32C2B400581290 /* DetailViewController.swift */, + ); + path = Controllers; + sourceTree = ""; + }; 6E52A5432A2108FD009A81D2 = { isa = PBXGroup; children = ( @@ -99,13 +163,9 @@ 6E52A54E2A2108FD009A81D2 /* ToDoListOfTDD */ = { isa = PBXGroup; children = ( - 6E52A54F2A2108FD009A81D2 /* AppDelegate.swift */, - 6E52A5512A2108FD009A81D2 /* SceneDelegate.swift */, - 6E52A5532A2108FD009A81D2 /* ViewController.swift */, - 6E52A5552A2108FD009A81D2 /* Main.storyboard */, - 6E52A5582A2108FE009A81D2 /* Assets.xcassets */, - 6E52A55A2A2108FE009A81D2 /* LaunchScreen.storyboard */, - 6E52A55D2A2108FE009A81D2 /* Info.plist */, + 653CF0872A32BA1A00581290 /* SupportingFiles */, + 653CF0862A32BA0900581290 /* Resources */, + 653CF0852A32B9F800581290 /* Sources */, ); path = ToDoListOfTDD; sourceTree = ""; @@ -258,9 +318,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6E52A5542A2108FD009A81D2 /* ViewController.swift in Sources */, + 6E52A5542A2108FD009A81D2 /* MainViewController.swift in Sources */, + 653CF0822A319A3500581290 /* InputViewController.swift in Sources */, 6E52A5502A2108FD009A81D2 /* AppDelegate.swift in Sources */, 6E52A5522A2108FD009A81D2 /* SceneDelegate.swift in Sources */, + 653CF0842A31BB2600581290 /* MainTableViewCell.swift in Sources */, + 653CF0802A31998200581290 /* Model.swift in Sources */, + 653CF08D2A32C2B400581290 /* DetailViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -438,12 +502,13 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = ToDoListOfTDD/Info.plist; + INFOPLIST_FILE = ToDoListOfTDD/SupportingFiles/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"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -451,9 +516,12 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.AKAPUCH.ToDoListOfTDD; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -465,12 +533,13 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = ToDoListOfTDD/Info.plist; + INFOPLIST_FILE = ToDoListOfTDD/SupportingFiles/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"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -478,9 +547,12 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.AKAPUCH.ToDoListOfTDD; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; diff --git a/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.xcworkspace/xcuserdata/openbible.xcuserdatad/UserInterfaceState.xcuserstate b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.xcworkspace/xcuserdata/openbible.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..8b4c0e4 Binary files /dev/null and b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/project.xcworkspace/xcuserdata/openbible.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..e9c84b2 --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcschemes/xcschememanagement.plist b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..ebe52af --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD.xcodeproj/xcuserdata/openbible.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + ToDoListOfTDD.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/ToDoListOfTDD/ToDoListOfTDD/.DS_Store b/ToDoListOfTDD/ToDoListOfTDD/.DS_Store new file mode 100644 index 0000000..a928db5 Binary files /dev/null and b/ToDoListOfTDD/ToDoListOfTDD/.DS_Store differ diff --git a/ToDoListOfTDD/ToDoListOfTDD/Base.lproj/Main.storyboard b/ToDoListOfTDD/ToDoListOfTDD/Base.lproj/Main.storyboard deleted file mode 100644 index 25a7638..0000000 --- a/ToDoListOfTDD/ToDoListOfTDD/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/AccentColor.colorset/Contents.json b/ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/AccentColor.colorset/Contents.json rename to ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/AppIcon.appiconset/Contents.json b/ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/AppIcon.appiconset/Contents.json rename to ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/Contents.json b/ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/Contents.json similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/Assets.xcassets/Contents.json rename to ToDoListOfTDD/ToDoListOfTDD/Resources/Assets.xcassets/Contents.json diff --git a/ToDoListOfTDD/ToDoListOfTDD/AppDelegate.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/AppDelegate.swift similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/AppDelegate.swift rename to ToDoListOfTDD/ToDoListOfTDD/Sources/AppDelegate.swift diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/DetailViewController.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/DetailViewController.swift new file mode 100644 index 0000000..9de5a1a --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/DetailViewController.swift @@ -0,0 +1,66 @@ +// +// DetailViewController.swift +// ToDoListOfTDD +// +// Created by 편성경 on 2023/06/09. +// + +import UIKit +import MapKit + +class DetailViewController: UIViewController { + + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var locationLabel: UILabel! + + @IBOutlet weak var mapView: MKMapView! + + var data: Model? + + override func viewDidLoad() { + super.viewDidLoad() + + setData() + } + + func setData() { + titleLabel.text = data?.title + locationLabel.text = data?.location + + getMapData() + } + + // MARK: - MapView 설정 + func getMapData() { + let geocoder = CLGeocoder() + + let address = data!.location + + // 주소 -> 위도, 경도 변환 + geocoder.geocodeAddressString(address) { placemarks, error in + if let error = error { + print("Geocoder Error : \(error.localizedDescription)") + return + } + + if let placemark = placemarks?.first { + let location = placemark.location + if let coordinate = location?.coordinate { + // 위치 + let region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000) + + // 핀(Annotation) + let annotation = MKPointAnnotation() + annotation.coordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) + annotation.title = self.data?.title + annotation.subtitle = self.data?.description + + self.mapView.addAnnotation(annotation) + self.mapView.setRegion(region, animated: true) + } + } + } + } + + +} diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/InputViewController.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/InputViewController.swift new file mode 100644 index 0000000..5760d3c --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/InputViewController.swift @@ -0,0 +1,60 @@ +// +// InputViewController.swift +// ToDoListOfTDD +// +// Created by 편성경 on 2023/06/08. +// + +import UIKit + +class InputViewController: UIViewController { + + @IBOutlet weak var titleTextField: UITextField! + @IBOutlet weak var locationTextField: UITextField! + @IBOutlet weak var descriptionTextField: UITextField! + @IBOutlet weak var datePicker: UIDatePicker! + + var mainVC: MainViewController! + + override func viewDidLoad() { + super.viewDidLoad() + + } + + + // MARK: - Save Button Tapped + @IBAction func doSave(_ sender: UIButton) { + // 유효성 검사 + guard let titleString = titleTextField.text, titleString.count > 0 else { + return + } + + guard let locationString = locationTextField.text, locationString.count > 0 else { + return + } + + guard let descriptionString = descriptionTextField.text, descriptionString.count > 0 else { + return + } + + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy/MM/dd" + + let formattedDate = dateFormatter.string(from: datePicker.date) + + let inputData = Model(title: titleString, location: locationString, description: descriptionString, time: formattedDate) + + mainVC.data.append(inputData) + mainVC.data.sort(by: { $0.time < $1.time }) // 날짜 순서대로 정렬 + mainVC.tableView.reloadData() + + dismiss(animated: true) + } + + // MARK: - Cancel Button Tapped + @IBAction func doCancel(_ sender: UIButton) { + dismiss(animated: true) + } + + +} diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/MainViewController.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/MainViewController.swift new file mode 100644 index 0000000..0c43275 --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Controllers/MainViewController.swift @@ -0,0 +1,68 @@ +// +// ViewController.swift +// ToDoListOfTDD +// +// Created by 최우태 on 2023/05/27. +// + +import UIKit + +class MainViewController: UIViewController { + + @IBOutlet weak var tableView: UITableView! + + var data = [Model]() + + override func viewDidLoad() { + super.viewDidLoad() + + // 실행 시 데이터가 없으면 InputView present + if data.isEmpty { + goInput() + } + + tableView.delegate = self + tableView.dataSource = self + } + + // MARK: - Input Button Tapped + @IBAction func inputButtonTapped(_ sender: UIBarButtonItem) { + goInput() + } + + // MARK: - InputView Present + func goInput() { + guard let inputVC = storyboard?.instantiateViewController(withIdentifier: "InputViewController") as? InputViewController else { + return + } + inputVC.mainVC = self + present(inputVC, animated: true, completion: nil) + } + +} + +// MARK: - MainViewController UITableView Extension +extension MainViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return data.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell", for: indexPath) as! MainTableViewCell + cell.titleLabel.text = data[indexPath.row].title + cell.locationLabel.text = data[indexPath.row].location + cell.timeLabel.text = data[indexPath.row].time + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let detailVC = storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { + return + } + detailVC.data = data[indexPath.row] + navigationController?.pushViewController(detailVC, animated: true) + } + +} + diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Models/Model.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/Models/Model.swift new file mode 100644 index 0000000..20e167e --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Models/Model.swift @@ -0,0 +1,17 @@ +// +// Model.swift +// ToDoListOfTDD +// +// Created by 편성경 on 2023/06/08. +// + +import Foundation + +struct Model { + + let title: String + let location: String + let description: String + let time: String + +} diff --git a/ToDoListOfTDD/ToDoListOfTDD/SceneDelegate.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/SceneDelegate.swift similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/SceneDelegate.swift rename to ToDoListOfTDD/ToDoListOfTDD/Sources/SceneDelegate.swift diff --git a/ToDoListOfTDD/ToDoListOfTDD/Base.lproj/LaunchScreen.storyboard b/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from ToDoListOfTDD/ToDoListOfTDD/Base.lproj/LaunchScreen.storyboard rename to ToDoListOfTDD/ToDoListOfTDD/Sources/Views/Base.lproj/LaunchScreen.storyboard diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/Base.lproj/Main.storyboard b/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f87dd2d --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/Base.lproj/Main.storyboard @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/MainTableViewCell.swift b/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/MainTableViewCell.swift new file mode 100644 index 0000000..f82b973 --- /dev/null +++ b/ToDoListOfTDD/ToDoListOfTDD/Sources/Views/MainTableViewCell.swift @@ -0,0 +1,16 @@ +// +// MainTableViewCell.swift +// ToDoListOfTDD +// +// Created by 편성경 on 2023/06/08. +// + +import UIKit + +class MainTableViewCell: UITableViewCell { + + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var locationLabel: UILabel! + @IBOutlet weak var timeLabel: UILabel! + +} diff --git a/ToDoListOfTDD/ToDoListOfTDD/Info.plist b/ToDoListOfTDD/ToDoListOfTDD/SupportingFiles/Info.plist similarity index 89% rename from ToDoListOfTDD/ToDoListOfTDD/Info.plist rename to ToDoListOfTDD/ToDoListOfTDD/SupportingFiles/Info.plist index dd3c9af..9d5b2f6 100644 --- a/ToDoListOfTDD/ToDoListOfTDD/Info.plist +++ b/ToDoListOfTDD/ToDoListOfTDD/SupportingFiles/Info.plist @@ -2,6 +2,8 @@ + NSLocationWhenInUseUsageDescription + 지도 권한 필요 UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/ToDoListOfTDD/ToDoListOfTDD/ViewController.swift b/ToDoListOfTDD/ToDoListOfTDD/ViewController.swift deleted file mode 100644 index 11194e8..0000000 --- a/ToDoListOfTDD/ToDoListOfTDD/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// ToDoListOfTDD -// -// Created by 최우태 on 2023/05/27. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/ToDoTDD_step1.gif b/ToDoTDD_step1.gif new file mode 100644 index 0000000..7d81728 Binary files /dev/null and b/ToDoTDD_step1.gif differ