Skip to content

Commit

Permalink
Merge pull request #15 from boostcampwm-2022/feature/BrowseCell
Browse files Browse the repository at this point in the history
Browse cell 일부 구현
  • Loading branch information
jinwoong16 committed Nov 16, 2022
2 parents 905fcbb + 30219bd commit 5180632
Show file tree
Hide file tree
Showing 9 changed files with 405 additions and 234 deletions.
48 changes: 40 additions & 8 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
3449AD6029222B3900B87619 /* UserInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3449AD5F29222B3900B87619 /* UserInfoCell.swift */; };
349955122923220E007AB99E /* SwiftUIPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349955112923220E007AB99E /* SwiftUIPreview.swift */; };
3499551529232533007AB99E /* UIColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499551429232533007AB99E /* UIColor+.swift */; };
3499551E29233DEF007AB99E /* QuestCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499551D29233DEF007AB99E /* QuestCell.swift */; };
3499552029234637007AB99E /* CustomProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499551F29234637007AB99E /* CustomProgressBar.swift */; };
3499552329234D5F007AB99E /* BrowseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499552229234D5F007AB99E /* BrowseCell.swift */; };
3499552729235D1E007AB99E /* BrowseItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499552629235D1E007AB99E /* BrowseItemViewModel.swift */; };
349955292923600A007AB99E /* BrowseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349955282923600A007AB99E /* BrowseViewController.swift */; };
3499552B29236041007AB99E /* BrowseViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3499552A29236041007AB99E /* BrowseViewModel.swift */; };
34ACC32D291DE9C000741371 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34ACC32C291DE9C000741371 /* AppDelegate.swift */; };
34ACC32F291DE9C000741371 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34ACC32E291DE9C000741371 /* SceneDelegate.swift */; };
34ACC336291DE9C100741371 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34ACC335291DE9C100741371 /* Assets.xcassets */; };
Expand All @@ -28,8 +34,6 @@
34ACC364291DEF6100741371 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 34ACC363291DEF6100741371 /* FirebaseFirestore */; };
34ACC366291DEF6100741371 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 34ACC365291DEF6100741371 /* FirebaseStorage */; };
34ACC36C291DF0DD00741371 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 34ACC36B291DF0DD00741371 /* GoogleService-Info.plist */; };
9B1CFB392922AFC700CCE97A /* QuestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B1CFB362922763E00CCE97A /* QuestView.swift */; };
9B1CFB3B2922BBDA00CCE97A /* BrowseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B1CFB342922460100CCE97A /* BrowseCell.swift */; };
B50078D629222F3F0070AFC4 /* CircleCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50078D529222F3F0070AFC4 /* CircleCheckView.swift */; };
B58DFC0A29227DA800C68A4B /* CalendarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58DFC0929227DA800C68A4B /* CalendarCell.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -57,6 +61,12 @@
3449AD5F29222B3900B87619 /* UserInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfoCell.swift; sourceTree = "<group>"; };
349955112923220E007AB99E /* SwiftUIPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIPreview.swift; sourceTree = "<group>"; };
3499551429232533007AB99E /* UIColor+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+.swift"; sourceTree = "<group>"; };
3499551D29233DEF007AB99E /* QuestCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestCell.swift; sourceTree = "<group>"; };
3499551F29234637007AB99E /* CustomProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomProgressBar.swift; sourceTree = "<group>"; };
3499552229234D5F007AB99E /* BrowseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseCell.swift; sourceTree = "<group>"; };
3499552629235D1E007AB99E /* BrowseItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseItemViewModel.swift; sourceTree = "<group>"; };
349955282923600A007AB99E /* BrowseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseViewController.swift; sourceTree = "<group>"; };
3499552A29236041007AB99E /* BrowseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseViewModel.swift; sourceTree = "<group>"; };
34ACC329291DE9C000741371 /* DailyQuest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DailyQuest.app; sourceTree = BUILT_PRODUCTS_DIR; };
34ACC32C291DE9C000741371 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
34ACC32E291DE9C000741371 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand All @@ -69,8 +79,6 @@
34ACC34D291DE9C100741371 /* DailyQuestUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyQuestUITests.swift; sourceTree = "<group>"; };
34ACC34F291DE9C100741371 /* DailyQuestUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyQuestUITestsLaunchTests.swift; sourceTree = "<group>"; };
34ACC36B291DF0DD00741371 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
9B1CFB342922460100CCE97A /* BrowseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseCell.swift; sourceTree = "<group>"; };
9B1CFB362922763E00CCE97A /* QuestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestView.swift; sourceTree = "<group>"; };
B50078D529222F3F0070AFC4 /* CircleCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleCheckView.swift; sourceTree = "<group>"; };
B58DFC0929227DA800C68A4B /* CalendarCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarCell.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -121,8 +129,8 @@
isa = PBXGroup;
children = (
3499551C292332DE007AB99E /* Cells */,
9B1CFB362922763E00CCE97A /* QuestView.swift */,
B50078D529222F3F0070AFC4 /* CircleCheckView.swift */,
3499551F29234637007AB99E /* CustomProgressBar.swift */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -175,6 +183,8 @@
3499551A292332B2007AB99E /* Browse */ = {
isa = PBXGroup;
children = (
3499552429235034007AB99E /* View */,
349955252923503C007AB99E /* ViewModel */,
);
path = Browse;
sourceTree = "<group>";
Expand All @@ -189,13 +199,31 @@
3499551C292332DE007AB99E /* Cells */ = {
isa = PBXGroup;
children = (
9B1CFB342922460100CCE97A /* BrowseCell.swift */,
B58DFC0929227DA800C68A4B /* CalendarCell.swift */,
3449AD5F29222B3900B87619 /* UserInfoCell.swift */,
3499551D29233DEF007AB99E /* QuestCell.swift */,
3499552229234D5F007AB99E /* BrowseCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
3499552429235034007AB99E /* View */ = {
isa = PBXGroup;
children = (
349955282923600A007AB99E /* BrowseViewController.swift */,
);
path = View;
sourceTree = "<group>";
};
349955252923503C007AB99E /* ViewModel */ = {
isa = PBXGroup;
children = (
3499552629235D1E007AB99E /* BrowseItemViewModel.swift */,
3499552A29236041007AB99E /* BrowseViewModel.swift */,
);
path = ViewModel;
sourceTree = "<group>";
};
34ACC320291DE9C000741371 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -434,17 +462,21 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9B1CFB3B2922BBDA00CCE97A /* BrowseCell.swift in Sources */,
3499552029234637007AB99E /* CustomProgressBar.swift in Sources */,
3499552329234D5F007AB99E /* BrowseCell.swift in Sources */,
3499551E29233DEF007AB99E /* QuestCell.swift in Sources */,
3449AD5D2922197000B87619 /* User.swift in Sources */,
B50078D629222F3F0070AFC4 /* CircleCheckView.swift in Sources */,
3499552729235D1E007AB99E /* BrowseItemViewModel.swift in Sources */,
349955292923600A007AB99E /* BrowseViewController.swift in Sources */,
B58DFC0A29227DA800C68A4B /* CalendarCell.swift in Sources */,
3499551529232533007AB99E /* UIColor+.swift in Sources */,
34ACC32D291DE9C000741371 /* AppDelegate.swift in Sources */,
3499552B29236041007AB99E /* BrowseViewModel.swift in Sources */,
3449AD5B2922164B00B87619 /* Quest.swift in Sources */,
349955122923220E007AB99E /* SwiftUIPreview.swift in Sources */,
3449AD6029222B3900B87619 /* UserInfoCell.swift in Sources */,
34ACC32F291DE9C000741371 /* SceneDelegate.swift in Sources */,
9B1CFB392922AFC700CCE97A /* QuestView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
8 changes: 7 additions & 1 deletion DailyQuest/DailyQuest/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// 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 }
let cont = BrowseViewController.create(with: BrowseViewModel())
self.window = UIWindow(windowScene: windowScene)
self.window?.rootViewController = cont
self.window?.makeKeyAndVisible()

return
}

func sceneDidDisconnect(_ scene: UIScene) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// BrowseViewController.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/15.
//

import UIKit

import RxSwift
import RxCocoa

final class BrowseViewController: UITableViewController {
private var viewModel: BrowseViewModel!
private var disposableBag = DisposeBag()

// MARK: - Life Cycle
static func create(with viewModel: BrowseViewModel) -> BrowseViewController {
let view = BrowseViewController()
view.viewModel = viewModel
return view
}

override func viewDidLoad() {
super.viewDidLoad()

configure()
bind()
}

/**
table view의 기본 정보를 설정합니다.
*/
private func configure() {
// 셀 사이사이의 구분선을 제거합니다.
tableView.separatorStyle = .none

tableView.allowsSelection = false

// 델리게이트와 데이터소스를 rx로 재설정합니다.
tableView.delegate = nil
tableView.dataSource = nil
tableView.rx.setDelegate(self).disposed(by: disposableBag)

// BrowseCell을 등록합니다.
tableView.register(BrowseCell.self, forCellReuseIdentifier: BrowseCell.reuseIdentifier)
}

private func bind() {
viewModel
.data
.bind(to: tableView.rx.items(cellIdentifier: BrowseCell.reuseIdentifier, cellType: BrowseCell.self)) { row, item, cell in
cell.setup(with: BrowseItemViewModel(user: item.0, quests: item.1))
}
.disposed(by: disposableBag)
}
}

extension BrowseViewController {
/**
하나의 BrowseCell의 크기를 결정합니다. BrowseCell내의 QuestCell의 개수만큼 크기가 늘어납니다.
+20은 margins으로 인해 추가된 값입니다.
*/
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return (75.0 * CGFloat(viewModel.cellCount[indexPath.row])) + 20 + 75
}

/**
viewModel에서 총 몇개의 BrowseCell을 만들어야하는지 결정합니다.
viewModel에는 UseCase를 통해 들어온 (User, [Quest]) 데이터에서 퀘스트의 **길이** 정보를 담는 프로퍼티(정ㅅ배열)가 있어야 합니다.
Note. 여기에서는 Quest 정보 자체가 필요하진 않습니다. 해당 배열의 아이템들은 위에서 사용할, BrowseCell의 크기를 결정하고,
배열 자체의 길이는 이 메서드의 결과를 결정합니다.
*/
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.cellCount.count
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// BrowseCellItemModel.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/15.
//

import Foundation

final class BrowseItemViewModel {
let user: User
let quests: [Quest]

init(user: User, quests: [Quest]) {
self.user = user
self.quests = quests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// BrowseViewModel.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/15.
//

import Foundation

import RxSwift

final class BrowseViewModel {
let user1 = User(uuid: UUID(), nickName: "jinwoong", profile: Data(), backgroundImage: Data(), description: "")
let quests1 = [
Quest(title: "물마시기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 2, totalCount: 5),
Quest(title: "코딩하기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 0, totalCount: 10)
]

let user2 = User(uuid: UUID(), nickName: "someone", profile: Data(), backgroundImage: Data(), description: "")
let quests2 = [
Quest(title: "물마시기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 4, totalCount: 5),
Quest(title: "책읽기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 9, totalCount: 20),
Quest(title: "달리기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 4, totalCount: 9),
Quest(title: "잠자기", startDay: Date(), endDay: Date(), repeat: 1, currentCount: 1, totalCount: 1)
]

let data: Observable<[(User, [Quest])]>

let cellCount = [2, 4]

init() {
self.data = .just([(user1, quests1), (user2, quests2)])
}
}

/**
Usecase
- fetching quests, it contains user and his quests.
*/
Loading

0 comments on commit 5180632

Please sign in to comment.