์ด์์ด ์ผ์์ด ๋๋ ํ๊ณ , 4most
๊ฐ๋ฐ๊ธฐ๊ฐ: 2020.12.27 ~ 2021.01.16
์ด์ ์ง | ์ ์ค์ | ์ฅํ๋ น |
---|---|---|
lee-yujinn | YoonAh-dev | hryeong66 |
๋ก๊ทธ์ธ/ํ์๊ฐ์
๊ธฐ๋ก ๋ชฉํ |
ํ๊ณ ๋ง์ดํ์ด์ง ์ค์ |
ํค์๋ ์ค์ ๋ง์ดํ์ด์ง ํค์๋ |
์ฃผ์๊ธฐ๋ฅ | ์์ธ๊ธฐ๋ฅ | ์ฐ์ ์์ | ๋ด๋น์ | ๊ตฌํ |
---|---|---|---|---|
๋ก๊ทธ์ธ/ํ์๊ฐ์ | ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ | P1 |
์ด์ ์ง | โญ๏ธ |
์๋๋ก๊ทธ์ธ | P2 |
์ด์ ์ง | โญ๏ธ | |
ํค์๋ ์ค์ | ํค์๋ ์ ํ | P1 |
์ฅํ๋ น | โญ๏ธ |
ํค์๋ ์ถ๊ฐ ๋ฐ ์ญ์ | P1 |
์ฅํ๋ น | โญ๏ธ | |
ํค์๋ ์ฐ์ ์์ ์ง์ | P1 |
์ฅํ๋ น | โญ๏ธ | |
ํค์๋ ์ ์ ์์ฑ | P1 |
์ฅํ๋ น | โญ๏ธ | |
๊ธฐ๋ก | ๊ธฐ๋ก ๋ ์ง๋ณ ์กฐํ | P1 |
์ด์ ์ง | โญ๏ธ |
ํค์๋ ๋ณ ๊ธฐ๋ก ์ถ๊ฐ | P1 |
์ด์ ์ง | โญ๏ธ | |
๊ธฐ๋ก ์์ธ ํ์ด์ง | P1 |
์ด์ ์ง | โญ๏ธ | |
๊ธฐ๋ก ์์ ๋ฐ ์ญ์ | P1 |
์ด์ ์ง | โญ๏ธ | |
๊ธฐ๋ก ๋ ์ง ๋ณ๊ฒฝ | P1 |
์ด์ ์ง | โญ๏ธ | |
๋ชฉํ | ๋ชฉํ ์ฃผ์ฐจ๋ณ ์กฐํ | P2 |
์ด์ ์ง | โญ๏ธ |
๋ชฉํ ์์ธ ํ์ด์ง | P2 |
์ด์ ์ง | โญ๏ธ | |
ํค์๋ ๋ณ ๋ชฉํ ์ถ๊ฐ | P2 |
์ด์ ์ง | โญ๏ธ | |
๋ชฉํ ์์ ๋ฐ ์ญ์ | P2 |
์ด์ ์ง | โญ๏ธ | |
๋ชฉํ ๋ฌ์ฑ์ฌ๋ถ ์ฒดํฌ | P2 |
์ด์ ์ง | โญ๏ธ | |
๋ชฉํ ์ฃผ์ฐจ ๋ณ๊ฒฝ | P2 |
์ด์ ์ง | โญ๏ธ | |
ํ๊ณ | ๋ฆฌํฌํธ ์กฐํ | P1 |
์ ์ค์ | โญ๏ธ |
ํค์๋ ๋ณ ๋ฆฌํฌํธ ์กฐํ | P1 |
์ ์ค์ | โญ๏ธ | |
ํ๊ณ ์กฐํ | P1 |
์ ์ค์ | โญ๏ธ | |
ํ๊ณ ์์ฑ | P1 |
์ ์ค์ | โญ๏ธ | |
ํ๊ณ ์ฃผ์ฐจ ๋ณ๊ฒฝ | P1 |
์ ์ค์ | โญ๏ธ | |
๋ง์ดํ์ด์ง | ํค์๋ ์ฐ์ ์์ ๋ณ๊ฒฝ | P2 |
์ฅํ๋ น | โญ๏ธ |
ํค์๋ ์ ์ ์กฐํ | P2 |
์ฅํ๋ น | โญ๏ธ | |
ํค์๋ ์ถ๊ฐ ๋ฐ ์ญ์ | P2 |
์ฅํ๋ น | โญ๏ธ | |
๊ธฐ๋ก ํค์๋ ๋ฑ๋ก ๋ฐ ํด์ | P2 |
์ฅํ๋ น | โญ๏ธ | |
์ฌ์ฉ์ ์ ๋ณด ์กฐํ | P3 |
์ ์ค์ | โญ๏ธ | |
๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ | P3 |
์ ์ค์ | โญ๏ธ | |
ํ์ํํด | P3 |
์ ์ค์ | โญ๏ธ |
-
ํต์ฌ ๊ธฐ๋ฅ ๊ตฌํ ๋ฐฉ๋ฒ
-
ํค์๋ ์ค์
//KeywordSettingTVC - tableviewcell ์์ ๋ฒํผ ํด๋ฆญ delegate protocol SelectKeywordDelegate { func addSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) -> Bool func cancelSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) } } ///KeywordSettingVC extension KeywordSettingVC: SelectKeywordDelegate{ func addSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) -> Bool{ if selectedKeywordCount >= 8{ alertKeyword() return false }else{ if attitudeOfWork.contains(selectedText){ selectedKeywordList[1].append(selectedText) }else{ selectedKeywordList[0].append(selectedText) } selectedKeywordCount += 1 setButtonActive() return true } } func cancelSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) { var keywordIndex = -1 for i in 0...2{ keywordIndex = selectedKeywordList[i].firstIndex(of: selectedText) ?? -1 if keywordIndex != -1{ selectedKeywordList[i].remove(at: keywordIndex) selectedKeywordCount -= 1 setButtonActive() } } } }
tableview cell ์์ ํค์๋ ๋ฒํผ๋ค์ด ์์ต๋๋ค. ๊ทธ ๋ฒํผ์ ๋๋ ์ ๋, ๊ทธ ๋๋ฆฌ ๋ฒํผ์ ์ด๋ฆ์ด ๋ฌด์์ด์๋์ง, ํ์ฌ ๋๋ฆฐ ๋ฒํผ์ ๋ช๊ฐ์ธ์ง๋ฅผ ์์์ผํ๋ค. ๋ค๋ฅธ ๊ณ์ธต์ ๋ทฐ ์ฌ์ด์ ์ ๋ณด๋ฅผ ์ฒ์์๋ ์ด๋ป๊ฒ ์ฃผ๊ณ ๋ฐ์์ง ๋ชฐ๋ผ static ๋ณ์๋ก ๋๋ฆฐ ๊ฐฏ์๋ฅผ +,- ํ๋ค. ๊ทธ static ๋ณ์๊ฐ 8๊ฐ๊ฐ ๋์๋์ง ๊ฒ์ฌํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์๋ค. ์ด ๋ฌธ์ ๋ฅผ delegate๋ฅผ ์ด์ฉํ์ฌ ํด๊ฒฐํ์๋ค. ํ์ ๋ทฐ์ cell์ delegate ํจ์๋ฅผ ์ฌ์ฉํ๊ณ ๊ทธ ํจ์๋ฅผ ์์์ธ VC์์ ๊ตฌํํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์๋ค.
-
๊ธฐ๋ก
@IBAction func btnMoreTapped(_ sender: Any) { if sender is UIButton { isExpanded = !isExpanded sizingLabel.numberOfLines = isExpanded ? 0 : 1 labelBody.textColor = isExpanded ? UIColor.mainLightGray3 : UIColor.white labelBody.font = .myRegularSystemFont(ofSize: 15) sizingLabel.font = .myRegularSystemFont(ofSize: 15) buttonMore.setImage(isExpanded ? UIImage(named: "btn_chevron_down"): UIImage(named: "btn_chevron_up"), for: .normal) delegate?.moreTapped(cell: self) } } func moreTapped(cell: DetailTVC) { tableView.beginUpdates() tableView.endUpdates() }
๊ธฐ๋ก์ ๊ฐ์์ ๋ง๊ฒ ๋๋กญ๋ค์ด์ด ๋๋ฉฐ ์ ๋ณด๊ฐ ๋ณด์ฌ์ ธ์ผ ํ๋ ๋ถ๋ถ์์ ํ ์ด๋ธ๋ทฐ์ ๊ธธ์ด๊ฐ ๋์ ์ผ๋ก ๋ณํ์ด์ผ ํ๋ค. ํญ์ด ๋๋ฆฌ๋ฉด tableview๊ฐ ๋ ์ด์์์ ๋ค์ ์ก์ ์ ์๊ฒ ๋์ ์ธ ๊ธธ์ด๋ฅผ ๊ฐฑ์ ๋์ด์ผ ํด์ ํ ์ด๋ธ๋ทฐ์ ๊ธธ์ด๋ estimatedRowHeight๋ก ์ด๊ธฐ์ ์ก๊ณ automaticDimension์ ์ ์ฉ์์ผ์ฃผ์ด ๊ตฌํํ๋ค.
-
ํ๊ณ
func collectionView(_ collectionView: UICollectionView, heightForLabelAtIndexPath indexPath: IndexPath) -> CGFloat { let width = (collectionView.bounds.size.width - (collectionView.contentInset.left + collectionView.contentInset.right + 16 + 16 + 30)) / 2 - 30 let label: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.text = taskTitle[indexPath.item] label.preferredMaxLayoutWidth = width label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.contentMode = .scaleToFill label.font = .myBoldSystemFont(ofSize: 16) label.sizeToFit() let calculateHeight = label.intrinsicContentSize.height + 120 return calculateHeight }
ํ๊ณ ๋ทฐ์์ ํค์๋๋ณ ๋ฆฌํฌํธ ์์ธ ๊ธฐ๋ก์ ์กฐํํ ์ ํด๋น ํ๋ ๊ธฐ๋ก text๊ฐ ๊ฐ์ง๊ณ ์๋ Label ํฌ๊ธฐ์ ๋ฐ๋ผ ์ ์ height ํฌ๊ธฐ๊ฐ ๊ฐ๊ฐ ๋ค๋ฅธ UICollectionView๋ฅผ ์์ฑํด์ผ ํ์ต๋๋ค. ๋ฐ๋ผ์ UICollectionViewLayout ํ์ผ์ ๋ฐ๋ก ์์ฑํด collectionView์ ๋์ด๋ฅผ ์์ฑํ๋ collectionView ํจ์๋ฅผ overrideํ์ฌ Label์ ๋ฐ๋ผ์ ์ ํฌ๊ธฐ๋ฅผ ๋ค๋ฅด๊ฒ ์์ฑํ๋ ํจ์ collectionView๋ฅผ ๋ง๋ค์์ต๋๋ค. ํด๋น ํจ์์์๋ ๋ค์ด๊ฐ๋ Label์ ๋์ด๋ฅผ ๊ณ์ฐํด๋ด์ด ๊ฐ ์ ๋ง๋ค ๋ค๋ฅธ ๋์ด๋ฅผ ๊ฐ์ง ์ ์๋๋ก ํ์ต๋๋ค.
-
-
Extension์ ํตํด ์์ฑํ ๋ฉ์๋ ์ค๋ช
-
Extension+Date
extension Date { var startOfWeek: Date? { var gregorian = Calendar(identifier: .gregorian) gregorian.timeZone = TimeZone(secondsFromGMT: 0)! guard let monday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil } if Calendar.current.component(.weekday, from: monday) == 1{ //์ผ์์ผ์ผ๋ return gregorian.date(byAdding: .day, value: 1, to: monday) }else{ return gregorian.date(byAdding: .day, value: 2, to: monday) } } var endOfWeek: Date? { var gregorian = Calendar(identifier: .gregorian) gregorian.timeZone = TimeZone(secondsFromGMT: 0)! guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil } if Calendar.current.component(.weekday, from: self) == 1{ //์ผ์์ผ์ผ๋ return gregorian.date(byAdding: .day, value: 2, to: sunday) }else{ return gregorian.date(byAdding: .day, value: 7, to: sunday) } } }
์๋ฒ์์ ํต์ ์์ ํ์ฌ ์์ ์ฃผ์ฐจ์ ์์๋ ์ง์ ๋ง์ง๋ง๋ ์ง๋ฅผ ์ ๋์คํ์์ผ๋ก ๋ณํํด์ ๋ณด๋ด๊ธฐ ์ํด ์ฌ์ฉ
iOS์์ ์ ๊ณต๋๋ Calendar๋ ๋งค์ฃผ ์ผ์์ผ์ ์ฃผ์ ์์์ผ๋ก ๊ณ์ฐํ๊ธฐ ๋๋ฌธ์ ์์์ผ๋ถํฐ ๊ณ์ฐํ๋ ํฌ๋ชจ์คํธ์๋ ๋ง์ง ์์ ์ผ์์ผ์ธ ๊ฒฝ์ฐ๋ฅผ ์์ธ์ ์ผ๋ก ๊ณ์ฐํด์ ํ์ฌ ์์ ์ ์์๊ณผ ๋ ๋ ์ง๋ฅผ ๋ฆฌํด!
-
-
ํจ์
func set4Most() { } lowerCamelCase ์ฌ์ฉํ๊ณ ๋์ฌ๋ก ์์
-
๋ณ์
var fourMostMembers = 13 lowerCamelCase ์ฌ์ฉ
-
์์
let fourMostiOSDevelopers: [String] = ["์ ์ง", "์ค์", "ํ๋ น"] lowerCamelCase ์ฌ์ฉ
-
ํด๋์ค
class fourMost{ } UpperCamelCase ์ฌ์ฉ
-
ํ์ผ๋ช
์ฝ์ด ViewController VC
TableViewCell TVC
CollectionViewCell CVC
-
๋ฉ์๋
- ์ค์ ๊ด๋ จ ๋ฉ์๋๋
set
์ผ๋ก ์์func setNavigationBar() { }
- ์ค์ ๊ด๋ จ ๋ฉ์๋๋
-
self
๋ ์ต๋ํ ์ฌ์ฉ์ ์ง์ -
viewDidLoad()
์์๋ ํจ์ํธ์ถ๋ง- delegate ์ง์ , UI๊ด๋ จ ์ค์ ๋ฑ๋ฑ ๋ชจ๋ ํจ์๋ก
-
ํจ์๋
extension
์ ์ ์ํ๊ณ ์ ๋ฆฌextension
์ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ถ๋ฅ
๐ git branch
- master : ์ ํ์ผ๋ก ์ถ์๋ ์ ์๋ ๋ธ๋์น
- develop : ๋ค์ ์ถ์ ๋ฒ์ ์ ๊ฐ๋ฐํ๋ ๋ธ๋์น
- feature : ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๋ ๋ธ๋์น
- release : ์ด๋ฒ ์ถ์ ๋ฒ์ ์ ์ค๋นํ๋ ๋ธ๋์น
โ๏ธ git commit message
- [Feat] : ๊ธฐ๋ฅ์ถ๊ฐ
- [Fix] : ๋ฒ๊ทธ์์
- [Chore] : ๊ฐ๋จํ ์์
- [Docs] : ๋ฌธ์ ๋ฐ ๋ฆฌ๋๋ฏธ ์์ฑ
- [Merge] : ๋จธ์ง
-
Resourse : asset, info.plist, AppDelegate ๊ด๋ฆฌ
-
Source : Scene(flow ๋ณ๋ก ํด๋๋ง) -> Storyboard, VC, Network(API), Model ๋ฑ ๊ด๋ฆฌ
4Most_iOS |โโ Source โ โโโ Scene โ โโโ MyDaily.storyboard โ โโโ View โ โ โโโ Cell โ โ โโโ VC โ โโโ Network โ โโโ Service โ โโโ Response โ โโโ Resquest โโโ Resource |โโ Assets.xcassets |โโ LaunchScreen.storyboard |โโ AppDelegate.swift |โโ SceneDelegate.swift โโโ Info.plist