๋๋ํ ์ง์ฌ๋ค์ ์ํ ๊ธฐ๋ก์ฅ Ounce.
๊ณ ์์ด๋ค์ ์ ๋ง์ด ๊น๋ค๋ก์, ์ง์ฌ๋ค์ ์ฑ๊ณตํ๋ฅ ์ด ๋์ ์๋๋ฅผ ์ํด ๋จน์ฌ๋ณธ ์บฃํธ๋๋ฅผ ๋ฐ๋ก ๊ธฐ๋กํ๊ณ ์์ต๋๋ค. ์ ํฌ๋ ์ด๋ฌํ ์ง์ฌ๋ค์ ๊ณ ๋ฏผ์ ํด๊ฒฐํ๊ธฐ ์ํด ์ง๊ด์ ์ธ ๊ธฐ๋ก, ์๋ก์ ๋ชฉ๋ก ๊ณต์ , ์ ๋ง์ด ๋น์ทํ ๊ณ ์์ด ์ถ์ฒ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค.
๊ธฐ๋ก๋ถํฐ ์ ํ๊น์ง, ์จ์ค๊ฐ ํจ๊ปํฉ๋๋ค.
-
Xcode 11.5
-
iOS 13.0
-
Swift 5
๋ผ์ด๋ธ๋ฌ๋ฆฌ | ๋ชฉ์ |
---|---|
Alamofire | ์๋ฒ ํต์ |
Gedatsu | ์คํ ๋ ์ด์์ ์๋ฌ ๋๋ฒ๊น ๊ฒ์ถ |
Kingfisher | ์ด๋ฏธ์ง ์ฒ๋ฆฌ |
SnapKit | ์ฝ๋ ๋ ์ด์์ ์์ฑ |
SwiftKeychainWrapper | ์ ์ฅ์ ์ํธํ๋ฅผ ์ํด์ |
Then | ์ปดํฌ๋ํธ ์ฝ๋ ์์ฑ์ ์ฉ์ด๋ฅผ ์ํด |
YPImagePicker | ์ฌ์ง์ฒฉ ์ฌ์ฉ |
UPCarouselFlowLayout | Carousel effect |
iOSDropDown | DropDown ํจ๊ณผ |
CHIPageControl | ์ธ๋์ผ์ดํฐ |
SwiftGifOrigin | GIF ์ด๋ฏธ์ง ์ฌ์ฉ |
๊ธฐ๋ฅ | ์์ธ ๊ธฐ๋ฅ | ๋ด๋น | ๊ตฌํ ์ฌ๋ถ |
---|---|---|---|
์คํ๋์ | ์คํ๋์ | ์คํ | O |
๋ก๊ทธ์ธ | ๋ก๊ทธ์ธ | ์คํ | O |
ํ์๊ฐ์ | ์ด๋ฉ์ผ ์ธ์ฆ | ์คํ | O |
์์ด๋ ๊ฒ์ฆ | ์คํ | O | |
๋น๋ฐ๋ฒํธ ๊ฒ์ฆ | ์คํ | O | |
ํ์๊ฐ์ | ์คํ | O | |
ํ๋กํ ๋ฑ๋ก | ํ๋กํ ๋ฑ๋ก | ์คํ | O |
ํ ํ๋ฉด | ์ ๋ ฌ | ์ฃผ์ฐ | O |
ํํฐ | ์ฃผ์ฐ | O | |
๊ณ์ ์ ํ | ์ฃผ์ฐ | O | |
๊ณ์ ์ถ๊ฐ | ์ฃผ์ฐ | O | |
ํ๋ก์ | ํธ์ธ | O | |
ํ๋ก์ | ํธ์ธ | O | |
์ค์ | - | O | |
ํ๋กํ ์์ | - | O | |
์ค์ | ์ค์ ๋ฉ๋ด ๋ด๋ถ์์ ๋ก๊ทธ์์ | ์ฃผ์ฐ | O |
๊ธฐ๋กํ๊ธฐ | ๊ธฐ๋ก ํ๊ธฐ | ์ค์ง | O |
์ ํ ๊ฒ์ | ์ค์ง | O | |
์ ํ์ด ์์์ ์ ํ ์์ฑ๊ณผ ํจ๊ป ๊ธฐ๋ก | ์ค์ง | O | |
์ ํ | ์ ํ ๊ฒ์ | ์คํ | O |
๋๋ฌ๋ณด๊ธฐ | ๋๋ฌ๋ณด๊ธฐ ์นด๋ ๋ทฐ | ํธ์ธ | O |
๋ฆฌ๋ทฐ ์ถ๊ฐ | ๋ฆฌ๋ทฐ ์ถ๊ฐ | ์คํ | O |
๊นํธ์ธ
carousel effect์ ๋ํด ์๊ฒ๋์์ด๋น ๋ฐ autoLayout๋ฅผ programmatically๋ก ๊ตฌํ ๋ฐฉ๋ฒ์ ์๊ฒ๋์์ด๋น ํํ๐
let labelName = UILabel().then { $0.textColor = .black $0.backgroundColor = .white $0.textAlignment = .center $0.font = UIFont.systemFont(ofSize: 13) $0.text = "๊ฐ์์ด" } // Then์ ์ด์ฉํด์, ๋ผ๋ฒจ์ ์์ฑํ๊ณ ๊ฐ๋ ์ฑ์ ์ํด์ BrowseCvCell์ extension BrowseCVCell + constranint ์ ๋ง๋ค์์ต๋๋ค. ๊ทธ ํ์ func initial() { // Snapkit์ ์ด์ฉํ์ฌ programmatically autolayout์ ์ค์ ํด์ฃผ์์ต๋๋ค. contentView.addSubview(labelName) //contentView ์์ ๊ทธ๋ ค์ฃผ๊ณ labelName.snp.makeConstraints { (make) in make.leading.equalTo(contentView.snp.leading).inset(88) // label์ leading์ contentView์ leading์ constraint๋ฅผ ๊ฑธ์์ต๋๋ค. make.trailing.equalTo(contentView.snp.trailing).inset(87) // label์ trailing์ contentView์ trailing์ constraint๋ฅผ ๊ฑธ์์ต๋๋ค. make.top.equalTo(imgCatView.snp.bottom).inset(-10) // label์ top์ ๊ทธ label ์์ ์๋ ์ปดํฌ๋ํธ (imgCatView)์ bottom์ ๊ฑธ์์ต๋๋ค. ๊ธฐ์ค์ด bottom ์ด๋ฏ๋ก Inset ๊ฐ์ ์์๋ก ์ค์ ํ์์ต๋๋ค. } }
๋ฐ์ฃผ์ฐ
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 1{
return 49
}
else {
return 0
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 1 {
let headerCell = reviewTV.dequeueReusableCell(withIdentifier: "HeaderCell")
return headerCell
}
else{
let rect = CGRect(x: 0, y: 0, width: 0, height: 0)
let myView = UIView(frame: rect)
return myView
}
}
์ด์ค์ง
let custom = Bundle.main.loadNibNamed("PostSC", owner: self, options: nil)?[0] as! PostSC self.addScrollView.addSubview(custom)
์ค์คํ
๋์์ธํํธ์์ ์ํ๋ ์ปค์คํ ํญ๋ฐ๊ฐ ์์ด ์๋กญ๊ฒ ์ปค์คํ ํญ๋ฐ๋ฅผ ๋์ ํด๋ดค์ต๋ค~!
๋จผ์ ์ปค์คํ ํญ๋ฐ๋ฅผ ๊ตฌํํด์ค ํด๋์ค๊ฐ ํ์ํด ๋ง๋ค์ด์ค๋๋ค.
weak var addDelegate: RootTabBarDelegate? private lazy var addButton:UIButton = { return UIButton() }() override init(frame: CGRect) { super.init(frame: frame) UITabBar.clearShadow() addButton.setBackgroundImage(UIImage.init(named: "btnAdd"), for: .normal) addButton.addTarget(self, action: #selector(CustomTabBar.addButtonClick), for: .touchUpInside) self.addSubview(addButton) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc func addButtonClick(){ if addDelegate != nil{ addDelegate?.addClick() } } override func layoutSubviews() { super.layoutSubviews() let buttonX = self.frame.size.width/3 var index = 0 for barButton in self.subviews{ if barButton.isKind(of: NSClassFromString("UITabBarButton")!){ if index == 1{ /// Setting the Add Button Position addButton.frame.size = CGSize.init(width: (addButton.currentBackgroundImage?.size.width)!, height: (addButton.currentBackgroundImage?.size.height)!) addButton.center = CGPoint.init(x: self.center.x, y: self.frame.size.height/2 - 18) index += 1 } barButton.frame = CGRect.init(x: buttonX * CGFloat(index), y: 0, width: buttonX, height: self.frame.size.height) index += 1 } } self.bringSubviewToFront(addButton) } /// Rewrite the hitTest method, listen for the button click to make the highlighted tabbar part respond to the click override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { /// Determine whether it is the root controller if self.isHidden { /// tabbar hiding is not handled in the home page system return super.hitTest(point, with: event) }else{ /// Converting Money Touch Points to Buttons to Generate New Points let onButton = self.convert(point, to: self.addButton) /// Determine whether the new point is on the button if self.addButton.point(inside: onButton, with: event){ return addButton }else{ /// No System Processing on the Button return super.hitTest(point, with: event) } } }์ฌ๊ธฐ์ ์ฃผ์ ํด์ค Delegate ํจํด์ ๋ง๋ค์ด์ค๋๋ค
protocol RootTabBarDelegate:NSObjectProtocol { func addClick() }๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก ํญ๋ฐ ์ปจํธ๋กค๋ฌ์์ Delegate๋ฅผ ์ฃผ์ ๋ฐ๊ณ
extension TBC : RootTabBarDelegate{ }override func viewDidLoad() { super.viewDidLoad() let tab = CustomTabBar() tab.addDelegate = self self.setValue(tab, forKey: "tabBar") }addClick ์ฆ ์ปค์คํ ํ ๋ ๊ฐ์ด๋ฐ์ ๋ค์ด๊ฐ ๋ฒํผ์ ํด๋ฆญํ ๋ ์คํ๋ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์๋ฉด ๋ฉ๋๋ค,
func addClick() { let sb = UIStoryboard(name: "Post", bundle: nil) let vc = sb.instantiateViewController(withIdentifier: "PostNavVC") as! PostNavVC vc.modalPresentationStyle = .fullScreen self.present(vc, animated: true) }
๊นํธ์ธ / (์ฌ์)
์ฑ์ฅ
ํ์๋ค์ด ๋๋ฌด ์ข์์ ํ๋ณตํ๋ค. ์ด๋ ต์ง๋ง ์ฑ์ฅ ํ ์ ์์๋ ์ฆ๊ฑฐ์ด 3์ฃผ์๋ค.
๋ฐ์ฃผ์ฐ / (์ฐจ์ฅ. ์ฌ์ค ํ์ฅ๋ธ)
์ฑ์คํ ์ด ์ถ์ & ํ์ ๋ฅ๋ ฅ ์ฑ์ฅ
์ฐ๋ฆฌ ์จ์ค ์์ํ์โค๏ธ ์ฑ์คํ ์ด ๋ฑ๋ก ๊ณ ๊ณ ~~
์ด์ค์ง / (๋๋ฆฌ)
iOS ์ค๋ ฅ ์ฑ์ฅ & ์ฑ์คํ ์ด ์ถ์
์จ์ค ์ฌ๋ํด์โค๏ธ ๋ค๋ค 3์ฃผ๋์ ๊ณ ์๋ง์์ด์
์ค์คํ / (๋ถ์ฅ)
์ฑ์คํ ์ด ์ถ์
์ฐ๋ฆฌ ์ฌ์๋ค๊ณผ ํจ๊ป ์ฆ๊ฑฐ์ด 3์ฃผ๋ฅผ ๋ณด๋ผ ์ ์์ด์ ์์ฃผ ์ฆ๊ฑฐ์ด ์๊ฐ์ด์์ต๋๋ค.