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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions iBox/Sources/Model/MyPageItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,29 @@

import Foundation

struct MyPageSection {
var title: String
var items: [MyPageItem]
enum MyPageType {
case theme
case homeTab
case preload
case guide
case feedback
case developer

func toString() -> String {
switch self {
case .theme: "테마"
case .homeTab: "홈화면"
case .preload: "페이지 미리 로드"
case .guide: "이용 가이드"
case .feedback: "앱 피드백"
case .developer: "개발자 정보"
}
}

}

struct MyPageItem {
var title: String
var type: MyPageType
var description: String?
var flag: Bool?
}
70 changes: 55 additions & 15 deletions iBox/Sources/Presenter/MyPage/MyPageItemCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import UIKit

import SnapKit

class MyPageItemCell: UITableViewCell, BaseViewProtocol {
class MyPageItemCell: UITableViewCell {

// MARK: - UI
static let reuseIdentifier = "MyPageItemCell"
private var viewModel: MyPageCellViewModel?

// MARK: - UI Components

let titleLabel = UILabel().then {
$0.font = .systemFont(ofSize: 16)
Expand All @@ -22,48 +25,85 @@ class MyPageItemCell: UITableViewCell, BaseViewProtocol {
$0.textColor = .gray
}

let switchControl = UISwitch().then {
$0.onTintColor = .box2
}

let chevronButton = UIButton().then {
$0.configuration = .plain()
$0.configuration?.image = UIImage(systemName: "chevron.right")
$0.configuration?.preferredSymbolConfigurationForImage = .init(pointSize: 10, weight: .bold)
$0.tintColor = .systemGray3
}

// MARK: - initializer
// MARK: - Initializer

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
selectionStyle = .none // 셀 선택했을 때 회색으로 변하는 것 비활성화
setupProperty()
setupHierarchy()
setupLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - BaseViewProtocol
// MARK: - Setup Methods

func configureUI() {
private func setupProperty() {
backgroundColor = .clear
addSubview(titleLabel)
addSubview(descriptionLabel)
addSubview(chevronButton)

selectionStyle = .none
}

private func setupHierarchy() {
contentView.addSubview(titleLabel)
contentView.addSubview(switchControl)
contentView.addSubview(descriptionLabel)
contentView.addSubview(chevronButton)
}

private func setupLayout() {
titleLabel.snp.makeConstraints {
$0.left.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}

chevronButton.snp.makeConstraints {
$0.right.equalToSuperview().inset(20)
switchControl.snp.makeConstraints {
$0.right.equalToSuperview().inset(30)
$0.centerY.equalToSuperview()
$0.width.height.equalTo(20)
}

descriptionLabel.snp.makeConstraints {
$0.right.equalTo(chevronButton.snp.left).offset(-10)
$0.right.equalToSuperview().inset(30)
$0.centerY.equalToSuperview()
}

chevronButton.snp.makeConstraints {
$0.right.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
}

// MARK: - Bind ViewModel

func bindViewModel(_ viewModel: MyPageCellViewModel) {
self.viewModel = viewModel
titleLabel.text = viewModel.title

descriptionLabel.isHidden = true
switchControl.isHidden = true
chevronButton.isHidden = true

if let description = viewModel.description {
descriptionLabel.text = description
descriptionLabel.isHidden = false
} else if let flag = viewModel.flag {
switchControl.isOn = flag
switchControl.isHidden = false
} else {
chevronButton.isHidden = false
}
}

}
107 changes: 60 additions & 47 deletions iBox/Sources/Presenter/MyPage/MyPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
import Combine
import UIKit

class MyPageView: BaseView {

// MARK: - Properties
final class MyPageView: BaseView {

var delegate: MyPageViewDelegate?
private var viewModel: MyPageViewModel?
private var cancellables = Set<AnyCancellable>()

// MARK: - UI
// MARK: - UI Components

let profileView = UIView().then {
$0.isUserInteractionEnabled = true
Expand All @@ -40,7 +38,7 @@ class MyPageView: BaseView {
}

let tableView = UITableView().then {
$0.register(MyPageItemCell.self, forCellReuseIdentifier: "MyPageItemCell")
$0.register(MyPageItemCell.self, forCellReuseIdentifier: MyPageItemCell.reuseIdentifier)
$0.separatorStyle = .none
$0.sectionHeaderTopPadding = 0
$0.backgroundColor = .clear
Expand All @@ -50,30 +48,38 @@ class MyPageView: BaseView {

override init(frame: CGRect) {
super.init(frame: frame)
setupProperties()
setupProperty()
setupHierarchy()
setupLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - BaseViewProtocol
// MARK: - Setup Methods

private func setupProperties() {
private func setupProperty() {
tableView.delegate = self
tableView.dataSource = self

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(profileViewTapped))
profileView.addGestureRecognizer(tapGesture)
profileView.addGestureRecognizer(
UITapGestureRecognizer(
target: self,
action: #selector(profileViewTapped)
)
)
}

override func configureUI() {
private func setupHierarchy() {
addSubview(profileView)
profileView.addSubview(profileImageView)
profileView.addSubview(profileLabel)
profileView.addSubview(chevronButton)
addSubview(tableView)

}

private func setupLayout() {
profileView.snp.makeConstraints {
$0.left.top.right.equalToSuperview()
$0.height.equalTo(90)
Expand All @@ -91,7 +97,7 @@ class MyPageView: BaseView {
}

chevronButton.snp.makeConstraints {
$0.right.equalToSuperview().inset(20)
$0.right.equalToSuperview().inset(30)
$0.centerY.equalToSuperview()
$0.width.height.equalTo(20)
}
Expand All @@ -110,67 +116,74 @@ class MyPageView: BaseView {
.receive(on: RunLoop.main)
.sink { [weak self] event in
switch event {
case .updateMyPageSectionViewModels:
case .updateSectionViewModels:
self?.tableView.reloadData()
}
}.store(in: &cancellables)
}

// MARK: - functions
// MARK: - Action Functions

@objc func profileViewTapped() {
@objc private func profileViewTapped() {
delegate?.pushViewController(ProfileViewController())
}

@objc private func handleSwitchControlTap(_ controlSwitch: UISwitch) {
guard let viewModel = viewModel else { return }
viewModel.input.send(.setPreload(controlSwitch.isOn))
}

}

extension MyPageView: UITableViewDelegate, UITableViewDataSource {
extension MyPageView: UITableViewDelegate {

// 테이블 뷰의 섹션 개수 설정
func numberOfSections(in tableView: UITableView) -> Int {
guard let viewModel = viewModel else { return 0 }
return viewModel.myPageSectionViewModels.count
}

// 테이블 뷰의 행 개수 설정
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let viewModel = viewModel else { return 0 }
return viewModel.myPageSectionViewModels[section].model.items.count
}

// 테이블 뷰 셀 구성
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let viewModel = viewModel,
let cell = tableView.dequeueReusableCell(withIdentifier: "MyPageItemCell")
as? MyPageItemCell else { return UITableViewCell() }
let item = viewModel.myPageSectionViewModels[indexPath.section].model.items[indexPath.row]
cell.titleLabel.text = item.title
cell.descriptionLabel.text = item.description
return cell
}

// 셀의 높이 설정
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 65
return viewModel.sectionViewModels.count
}

// 섹션 헤더의 View 설정
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = .backgroundColor
return headerView
}

// 섹션 헤더의 높이 설정
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
return 20
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 55
}

// 테이블 뷰 셀이 선택되었을 때 실행되는 메서드
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let viewModel = viewModel else { return }
let item = viewModel.myPageSectionViewModels[indexPath.section].model.items[indexPath.row]
delegate?.pushViewController(indexPath)
let myPageItem = viewModel.sectionViewModels[indexPath.section].cellViewModels[indexPath.row].myPageItem
if (myPageItem.type != MyPageType.preload) {
delegate?.pushViewController(myPageItem.type)
}
}

}

extension MyPageView: UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let viewModel = viewModel else { return 0 }
return viewModel.sectionViewModels[section].cellViewModels.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let viewModel = viewModel,
let cell = tableView.dequeueReusableCell(withIdentifier: MyPageItemCell.reuseIdentifier)
as? MyPageItemCell else { return UITableViewCell() }
let cellViewModel = viewModel.sectionViewModels[indexPath.section].cellViewModels[indexPath.row]
cell.bindViewModel(cellViewModel)
if cellViewModel.flag != nil {
cell.switchControl.removeTarget(nil, action: nil, for: .valueChanged)
cell.switchControl.addTarget(self, action: #selector(handleSwitchControlTap), for: .valueChanged)
}
return cell
}

}
Loading