diff --git a/Instagram-iOS/Instagram-iOS.xcodeproj/project.pbxproj b/Instagram-iOS/Instagram-iOS.xcodeproj/project.pbxproj index 525959d..dfaf49c 100644 --- a/Instagram-iOS/Instagram-iOS.xcodeproj/project.pbxproj +++ b/Instagram-iOS/Instagram-iOS.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 372AAF732A20E7FC009212A8 /* DMTableviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372AAF722A20E7FC009212A8 /* DMTableviewCell.swift */; }; + 372AAF752A20E808009212A8 /* DMCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372AAF742A20E808009212A8 /* DMCollectionViewCell.swift */; }; + 372AAF772A20F90F009212A8 /* DMTableViewHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372AAF762A20F90F009212A8 /* DMTableViewHeader.swift */; }; + 372AAF952A24E3C4009212A8 /* DMTableViewCellHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372AAF942A24E3C4009212A8 /* DMTableViewCellHeader.swift */; }; 37C4BF062A1D3E86006FBFF6 /* SF-Pro-Text-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 37C4BF052A1D3E86006FBFF6 /* SF-Pro-Text-Bold.ttf */; }; 3E6CF47A2A14F43500DC3B2B /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6CF4792A14F43500DC3B2B /* BaseViewController.swift */; }; 3E6CF47C2A14F63700DC3B2B /* BaseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6CF47B2A14F63700DC3B2B /* BaseTableViewCell.swift */; }; @@ -63,6 +67,10 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 372AAF722A20E7FC009212A8 /* DMTableviewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMTableviewCell.swift; sourceTree = ""; }; + 372AAF742A20E808009212A8 /* DMCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMCollectionViewCell.swift; sourceTree = ""; }; + 372AAF762A20F90F009212A8 /* DMTableViewHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMTableViewHeader.swift; sourceTree = ""; }; + 372AAF942A24E3C4009212A8 /* DMTableViewCellHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMTableViewCellHeader.swift; sourceTree = ""; }; 37C4BF052A1D3E86006FBFF6 /* SF-Pro-Text-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Text-Bold.ttf"; sourceTree = ""; }; 37D49A6D2A17CE5C00FBCA0F /* UIStackView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+.swift"; sourceTree = ""; }; 3E6CF4792A14F43500DC3B2B /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; @@ -132,6 +140,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 372AAF702A20E7C8009212A8 /* Cell */ = { + isa = PBXGroup; + children = ( + 372AAF722A20E7FC009212A8 /* DMTableviewCell.swift */, + 372AAF742A20E808009212A8 /* DMCollectionViewCell.swift */, + 372AAF762A20F90F009212A8 /* DMTableViewHeader.swift */, + 372AAF942A24E3C4009212A8 /* DMTableViewCellHeader.swift */, + ); + path = Cell; + sourceTree = ""; + }; 3EEE766B2A17AEC000D0B80E /* NewPostImageCollection */ = { isa = PBXGroup; children = ( @@ -371,6 +390,7 @@ 7E8DF5942A1237120023948F /* DMList */ = { isa = PBXGroup; children = ( + 372AAF702A20E7C8009212A8 /* Cell */, 7E8DF5B32A1239100023948F /* DMList.swift */, ); path = DMList; @@ -483,6 +503,7 @@ 7E8DF59C2A1238770023948F /* EndPoint.swift in Sources */, 7E8DF59E2A12387E0023948F /* Service.swift in Sources */, 3E6FFF672A1D93F400166DCE /* Story.swift in Sources */, + 372AAF732A20E7FC009212A8 /* DMTableviewCell.swift in Sources */, 3E6CF47C2A14F63700DC3B2B /* BaseTableViewCell.swift in Sources */, 3E9683F02A1656A800D6DD30 /* SizeLiteral.swift in Sources */, 3E6FFF5D2A1BBC1100166DCE /* StoryContentViewController.swift in Sources */, @@ -496,6 +517,8 @@ 7E0148C02A1BEA9A0036147D /* StoryCollectionViewCell.swift in Sources */, 3E9683E62A16392900D6DD30 /* ImageLiteral.swift in Sources */, 3EEE76682A176C9100D0B80E /* NewPostImageCollectionViewCell.swift in Sources */, + 372AAF952A24E3C4009212A8 /* DMTableViewCellHeader.swift in Sources */, + 372AAF772A20F90F009212A8 /* DMTableViewHeader.swift in Sources */, 7E8DF5A02A1238840023948F /* Models.swift in Sources */, 7E0148BE2A1BE8780036147D /* StoryCollectionView.swift in Sources */, 3E6CF47E2A14F84500DC3B2B /* BaseCollectionViewCell.swift in Sources */, @@ -509,6 +532,7 @@ 7E8DF5AC2A1238D40023948F /* Font.swift in Sources */, 3E6FFF6F2A204B7800166DCE /* NetworkResult.swift in Sources */, 7E8DF5712A12306B0023948F /* SceneDelegate.swift in Sources */, + 372AAF752A20E808009212A8 /* DMCollectionViewCell.swift in Sources */, 7E8DF5982A12385E0023948F /* Protocol.swift in Sources */, 7E6608622A1FF08F007F2F8B /* TabBarViewController.swift in Sources */, 7E66085B2A1DD2B3007F2F8B /* PostCollectionViewCell.swift in Sources */, diff --git a/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMCollectionViewCell.swift b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMCollectionViewCell.swift new file mode 100644 index 0000000..ccdfc0b --- /dev/null +++ b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMCollectionViewCell.swift @@ -0,0 +1,46 @@ +// +// DMCollectionViewCell.swift +// Instagram-iOS +// +// Created by Joon Baek on 2023/05/26. +// + +import UIKit + +import SnapKit + +final class DMCollectionViewCell: BaseCollectionViewCell { + + // MARK: - UI Property + + let userProfileView = UserProfileView(usedView: .dm, storyStatus: .none) + + let usernameLabel: UILabel = { + let label = UILabel() + label.text = "hanyee" + label.font = .detail4 + label.textColor = .gray2 + return label + }() + + // MARK: - Layout + + override func setLayout() { + addSubview(userProfileView) + userProfileView.snp.makeConstraints { + $0.top.equalToSuperview().offset(10) + $0.leading.equalToSuperview().offset(7) + $0.width.height.equalTo(58) + $0.centerX.equalToSuperview() + } + + addSubview(usernameLabel) + usernameLabel.snp.makeConstraints { + $0.top.equalTo(userProfileView.snp.bottom).offset(10) + $0.centerX.equalTo(userProfileView) + } + } + + // MARK: - Custom Method + +} diff --git a/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewCellHeader.swift b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewCellHeader.swift new file mode 100644 index 0000000..68260f5 --- /dev/null +++ b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewCellHeader.swift @@ -0,0 +1,50 @@ +// +// DMTableViewCellHeader.swift +// Instagram-iOS +// +// Created by Joon Baek on 2023/05/29. +// + +import UIKit + +import SnapKit + +final class DMTableViewCellHeader: UITableViewHeaderFooterView { + + // MARK: - Property + + static let identifier = "DMTableViewCellHeader" + + // MARK: - UI Property + + private let sectionLabel: UILabel = { + let label = UILabel() + label.font = .bodyKorBold + label.textColor = .black1 + label.text = "메시지" + return label + }() + + // MARK: - Life Cycle + + override init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Layout + + private func setLayout() { + + addSubview(sectionLabel) + sectionLabel.snp.makeConstraints { + $0.leading.equalToSuperview().offset(16) + $0.bottom.equalToSuperview().offset(-8) + } + } +} diff --git a/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewHeader.swift b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewHeader.swift new file mode 100644 index 0000000..43050a6 --- /dev/null +++ b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableViewHeader.swift @@ -0,0 +1,136 @@ +// +// DMTableViewHeader.swift +// Instagram-iOS +// +// Created by Joon Baek on 2023/05/26. +// + +import UIKit + +import SnapKit + +final class DMTableViewHeader: UIView { + + private lazy var storyCollectionView: UICollectionView = { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + return collectionView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.font = .bodyKorBold + label.textColor = .black1 + label.text = "즐겨찾기" + return label + }() + + private let searchTextField: UITextField = { + let textField = UITextField() + textField.backgroundColor = .gray5 + textField.font = .body + //TODO: - 추후 placeholder 세팅 시 추가하겠습니다 + // textField.placeholder = "검색" + textField.layer.cornerRadius = 10 + return textField + }() + + private let sectionLabel: UILabel = { + let label = UILabel() + label.font = .bodyKorBold + label.textColor = .black1 + label.text = "메시지" + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + register() + configDelegate() + setLayout() + setStyle() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //MARK: - Setting + + private func register() { + storyCollectionView.register(DMCollectionViewCell.self, forCellWithReuseIdentifier: DMCollectionViewCell.identifier) + } + + private func configDelegate() { + storyCollectionView.delegate = self + storyCollectionView.dataSource = self + } + + private func setLayout() { + + addSubview(searchTextField) + searchTextField.snp.makeConstraints { + $0.top.centerX.equalToSuperview().offset(8) + $0.centerX.equalToSuperview() + $0.leading.equalToSuperview().offset(16) + $0.height.equalTo(35) + } + + addSubview(titleLabel) + titleLabel.snp.makeConstraints { + $0.top.equalTo(searchTextField.snp.bottom).offset(18) + $0.leading.equalToSuperview().offset(16) + } + + addSubview(storyCollectionView) + storyCollectionView.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(4) + $0.centerX.equalToSuperview() + $0.leading.equalToSuperview().offset(14) + $0.height.equalTo(90) + } + + addSubview(sectionLabel) + sectionLabel.snp.makeConstraints { + $0.leading.equalToSuperview().offset(16) + $0.bottom.equalToSuperview().offset(-8) + } + } + + private func setStyle() { + backgroundColor = .white1 + } +} + +//MARK: - UICollectionViewDelegateFlowLayout + +extension DMTableViewHeader: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: 72, height: 90) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { + return 4 + } +} + +//MARK: - UICollectionViewDataSource + +extension DMTableViewHeader: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 9 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DMCollectionViewCell.identifier, for: indexPath) as? DMCollectionViewCell else { return UICollectionViewCell() } + + return cell + } + + +} diff --git a/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableviewCell.swift b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableviewCell.swift new file mode 100644 index 0000000..9f26d02 --- /dev/null +++ b/Instagram-iOS/Instagram-iOS/Screens/DMList/Cell/DMTableviewCell.swift @@ -0,0 +1,70 @@ +// +// DMTableviewCell.swift +// Instagram-iOS +// +// Created by Joon Baek on 2023/05/26. +// + +import UIKit + +import SnapKit + +final class DMTableviewCell: BaseTableViewCell { + + // MARK: - UI Property + + let userProfileView = UserProfileView(usedView: .dm, storyStatus: .none) + + private let usernameLabel: UILabel = { + let label = UILabel() + label.text = "hanyee" + label.font = .detail2 + label.textColor = .gray2 + return label + }() + + private let textMessageLabel: UILabel = { + let label = UILabel() + label.text = "디엠디엠디엠" + label.font = .detail2kor + label.textColor = .gray2 + return label + }() + + private lazy var starButton: UIButton = { + let button = UIButton() + button.setImage(UIImage(systemName: "star.fill"), for: .normal) + button.tintColor = .systemYellow + return button + }() + + // MARK: - Layout + + override func setLayout() { + addSubview(userProfileView) + userProfileView.snp.makeConstraints { + $0.centerY.equalToSuperview() + $0.leading.equalToSuperview().offset(14) + $0.width.height.equalTo(58) + } + + addSubview(usernameLabel) + usernameLabel.snp.makeConstraints { + $0.top.equalToSuperview().offset(21) + $0.leading.equalTo(userProfileView.snp.trailing).offset(10) + } + + addSubview(textMessageLabel) + textMessageLabel.snp.makeConstraints { + $0.top.equalTo(usernameLabel.snp.bottom).offset(2) + $0.leading.equalTo(usernameLabel) + } + + addSubview(starButton) + starButton.snp.makeConstraints { + $0.centerY.equalToSuperview() + $0.trailing.equalToSuperview().offset(-9) + $0.width.height.equalTo(29) + } + } +} diff --git a/Instagram-iOS/Instagram-iOS/Screens/DMList/DMList.swift b/Instagram-iOS/Instagram-iOS/Screens/DMList/DMList.swift index e2286c0..d7f93ca 100644 --- a/Instagram-iOS/Instagram-iOS/Screens/DMList/DMList.swift +++ b/Instagram-iOS/Instagram-iOS/Screens/DMList/DMList.swift @@ -2,108 +2,124 @@ // DMList.swift // Instagram-iOS // -// Created by 김사랑 on 2023/05/15. +// Created by 백준 on 2023/05/15. // import UIKit - import SnapKit final class DMListViewController: BaseViewController { - // MARK: - Property - // MARK: - UI Property + private let headerView = DMTableViewHeader() + + let userNameLabel: UILabel = { + let label = UILabel() + label.font = .title1 + label.textColor = .black1 + label.text = "gosopt_cds_app1" + return label + }() + + let arrowDownButton = UIButton() + + let videoCallButton = UIButton() + + let newMessageButton = UIButton() + + let backButton: UIButton = { + let button = UIButton() + button.setImage(ImageLiteral.NavBar.DMList.arrowBack, for: .normal) + return button + }() + let customNaviView = UIView() - private let searchTextField: UITextField = { - let textField = UITextField() - textField.backgroundColor = .gray5 - textField.font = .body - textField.placeholder = "검색" - return textField + private let DMListTableView: UITableView = { + let tableView = UITableView(frame: .zero, style: .grouped) + tableView.separatorColor = .clear + tableView.register(DMTableViewCellHeader.self, forHeaderFooterViewReuseIdentifier: DMTableViewCellHeader.identifier) + tableView.register(DMTableviewCell.self, forCellReuseIdentifier: DMTableviewCell.identifier) + return tableView }() + // MARK: - Life Cycle override func viewDidLoad() { super.viewDidLoad() - setSearchTextFieldUI() + configTableView() } - // MARK: - Setting + private func configTableView() { + DMListTableView.delegate = self + DMListTableView.dataSource = self + } override func setNavigationBar() { super.setNavigationBar() - let backButton = UIButton() - backButton.setImage(ImageLiteral.NavBar.DMList.arrowBack, for: .normal) - let backButtonItem = UIBarButtonItem(customView: backButton) - let userNameLabel: UILabel = { - let label = UILabel() - label.font = .title1 - label.textColor = .black1 - label.text = "gosopt_cds_app1" - return label - }() - let userNameLabelItem = UIBarButtonItem(customView: userNameLabel) - let arrowButton = UIButton() - arrowButton.setImage(ImageLiteral.NavBar.DMList.arrowBottom, for: .normal) - - let arrowButtonItem = UIBarButtonItem(customView: arrowButton) - - let videoCallButton = UIButton() - videoCallButton.setImage(ImageLiteral.NavBar.DMList.camera, for: .normal) + let arrowDownButtonItem = UIBarButtonItem(customView: arrowDownButton) let videoCallButtonItem = UIBarButtonItem(customView: videoCallButton) - let newMessageButton = UIButton() - newMessageButton.setImage(ImageLiteral.NavBar.DMList.newDM, for: .normal) - let newMessageButtonItem = UIBarButtonItem(customView: newMessageButton) - navigationItem.leftBarButtonItems = [backButtonItem, userNameLabelItem, arrowButtonItem] - navigationItem.rightBarButtonItems = [videoCallButtonItem, newMessageButtonItem] + arrowDownButton.setImage(ImageLiteral.NavBar.DMList.arrowBottom, for: .normal) + videoCallButton.setImage(ImageLiteral.NavBar.DMList.camera, for: .normal) + newMessageButton.setImage(ImageLiteral.NavBar.DMList.newDM, for: .normal) + navigationItem.leftBarButtonItems = [backButtonItem, userNameLabelItem, arrowDownButtonItem] + navigationItem.rightBarButtonItems = [newMessageButtonItem, videoCallButtonItem] } override func setLayout() { - view.addSubview(customNaviView) customNaviView.snp.makeConstraints { $0.top.equalTo(view.safeAreaLayoutGuide.snp.top) $0.leading.trailing.equalToSuperview() } + + DMListTableView.tableHeaderView = headerView - view.addSubview(searchTextField) - searchTextField.snp.makeConstraints { - $0.top.equalTo(customNaviView.snp.bottom).offset(8) - $0.centerX.equalToSuperview() - $0.leading.equalToSuperview().offset(16) - $0.height.equalTo(35) + view.addSubview(DMListTableView) + DMListTableView.snp.makeConstraints { + $0.top.equalTo(view.safeAreaLayoutGuide) + $0.leading.bottom.trailing.equalToSuperview() } } - - // MARK: - Action Helper - - // MARK: - Custom Method - - private func setSearchTextFieldUI() { -// let searchImageView = UIImageView(image: ImageLiteral.NavBar.DMList.search) -// searchImageView.frame = CGRect(x: 0, y: 0, width: 10, height: searchTextField.frame.height) +} -// searchTextField.leftView = searchImageView -// searchTextField.leftViewMode = .always - - searchTextField.layer.cornerRadius = 10 - searchTextField.backgroundColor = .gray5 - searchTextField.font = .body - searchTextField.attributedPlaceholder = NSAttributedString(string: "검색", attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray]) - +//MARK: - UITableViewDelegate + +extension DMListViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + return DMTableViewHeader() + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 172 + 42 + } +} + +//MARK: - UITableViewDataSource + +extension DMListViewController: UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: DMTableviewCell.identifier, for: indexPath) as! DMTableviewCell + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 74 } }