Skip to content

Latest commit

ย 

History

History
442 lines (302 loc) ยท 16 KB

README.md

File metadata and controls

442 lines (302 loc) ยท 16 KB

๐Ÿ˜ธOunce

We are Ounceโ€ผ๏ธ

๋˜‘๋˜‘ํ•œ ์ง‘์‚ฌ๋“ค์„ ์œ„ํ•œ ๊ธฐ๋ก์žฅ Ounce.

๊ณ ์–‘์ด๋“ค์€ ์ž…๋ง›์ด ๊นŒ๋‹ค๋กœ์›Œ, ์ง‘์‚ฌ๋“ค์€ ์„ฑ๊ณตํ™•๋ฅ ์ด ๋†’์€ ์‹œ๋„๋ฅผ ์œ„ํ•ด ๋จน์—ฌ๋ณธ ์บฃํ‘ธ๋“œ๋ฅผ ๋”ฐ๋กœ ๊ธฐ๋กํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ์ด๋Ÿฌํ•œ ์ง‘์‚ฌ๋“ค์˜ ๊ณ ๋ฏผ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ง๊ด€์ ์ธ ๊ธฐ๋ก, ์„œ๋กœ์˜ ๋ชฉ๋ก ๊ณต์œ , ์ž…๋ง›์ด ๋น„์Šทํ•œ ๊ณ ์–‘์ด ์ถ”์ฒœ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ก๋ถ€ํ„ฐ ์„ ํƒ๊นŒ์ง€, ์˜จ์Šค๊ฐ€ ํ•จ๊ป˜ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽ ๋ชฉ์ฐจ



๐Ÿ“ฑ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

  • Xcode 11.5

  • iOS 13.0

  • Swift 5



๐Ÿ›  Library

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชฉ์ 
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


๐Ÿ“ Screenshots

  1. Splash

  2. Login

  3. Signup

  4. Register

  5. Home

  6. Setting

  7. Post

  8. Browse



๐Ÿ“š Project



๐Ÿ’ก์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ ๋œ ๊ฒƒ

๊น€ํ˜ธ์„ธ

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 ๊ฐ’์„ ์Œ์ˆ˜๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.                        
     }  
}

๋ฐ•์ฃผ์—ฐ

CollectionView๋ณด๋‹ค TableView๊ฐ€ ๋” ์ข‹๋‹ค^^ ๋‹ค ๋‚ด๊บผ ํ˜ธ๋กœ๋ก๐Ÿฅค

TableView middle cell ํ—ค๋”์— ๊ณ ์ •์‹œํ‚ค๊ธฐ
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
        }
        
    }

์ด์œค์ง„

NavigationController ์—ฐ๊ฒฐ ๋ฐ xib ํ™œ์šฉ ๋ฐฉ๋ฒ•์„ ๋‚ด๊ฐ€ ์ •๋ณตํ–ˆ๋‹ค๐Ÿ‹๏ธโ€โ™‚๏ธ

xib ํŒŒ์ผ์„ ํ™œ์šฉํ•ด์„œ ๋ทฐ ์žฌํ™œ์šฉํ•˜๋Š” ๊ฑธ ์ฒ˜์Œ ์‹œ๋„ํ•ด๋ดค๋‹ค,,,์‹ ๊ธฐ๋ฐฉ๊ธฐ,,,
    let custom = Bundle.main.loadNibNamed("PostSC", owner: self, options: nil)?[0] as! PostSC
        self.addScrollView.addSubview(custom)

์˜ค์ค€ํ˜„

custom TabBar ๋„์ „ํ•˜๊ธฐ ๋น ์ƒค๐ŸฅŠ

๋””์ž์ธํŒŒํŠธ์—์„œ ์›ํ•˜๋Š” ์ปค์Šคํ…€ ํƒญ๋ฐ”๊ฐ€ ์žˆ์–ด ์ƒˆ๋กญ๊ฒŒ ์ปค์Šคํ…€ ํƒญ๋ฐ”๋ฅผ ๋„์ „ํ•ด๋ดค์Šต๋‹ค~!

๋จผ์ € ์ปค์Šคํ…€ ํƒญ๋ฐ”๋ฅผ ๊ตฌํ˜„ํ•ด์ค„ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•ด ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

    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์ฃผ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด์„œ ์•„์ฃผ ์ฆ๊ฑฐ์šด ์‹œ๊ฐ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.