728x90
반응형

[Review] (2주차) 실습

2022.06.26 - [Swift] - [Xcode] iOS Swift 앱 개발 Byte Degree - week.02

 

[Xcode] iOS Swift 앱 개발 Byte Degree - week.02

iOS 아키텍처 패턴 중 애플에서는 기본적으로 MVC 패턴을 가이드함 Product Name: HelloiOS Organization Identifier: com.sehee Interface: Storyboard (other options: SwiftUI) Language: Swift (other option..

sarahee.tistory.com


Intro

Swift의 기본 기능, 리스트 및 그리드에 대해 알아보자

Xcode 실행시 기본 스토리보드

File > New > File (or command + n)

view controller 추가하기

Cocoa Touch Class > (Choose options for your new file) Class: StockRankViewController > Next > Create

좌측 Main Tab의 View Controller > 우측 Custom Class - Class 및 Identity - Storyboard ID: StockRankViewController 설정

* Storyboard ID에서 검색이 용이하도록(class 이름 자체가 unique한 id이므로 동일하게 설정해도 무방)

 

Main storyboard에서 우측 상단 + 버튼 클릭하여 UI components(objects) 선택

Collection View 추가

 


Auto rayout 설정

자식 뷰(Collection View)를 부모 뷰(View)에 연관되게 설정하기 위함

control 버튼을 누른 상태에서 Collection View → View 드래그

Shift를 누른 상태에서 클릭하여 다중 선택(상단 네개 Space to Safe Area 모두 클릭) 이후 Enter

View를 Code로 연결하기

해당하는 스토리보드(Collection View) 클릭 후 우측 상단 =(리스트) 아이콘 클릭

Assistant 클릭하여 새로운 view 생성

control 누른 상태에서 연결하고 싶은 뷰(Collection View) → 코드 드래그

name: collectionView > connect

import UIKit

class StockRankViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

Connection View Cell 내에 Label, Image View 추가 (option 누르고 드래그할 경우 복제)

Image View는 우측 Image View > Image에서 검색하여 변경 (e.g. heart.fill)

적용: option + command + =

//
//  StockRankViewController.swift
//  StockRank
//
//  Created by sehee on 2022/06/30.
//

import UIKit

class StockRankViewController: UIViewController {

    let stockList: [StockModel] = StockModel.list
    @IBOutlet weak var collectionView: UICollectionView!
    
    // Data, Presentation, Layout
    // Data: 어떤 떼이터? - stockList
    // Presentation: 셀을 어떻게 표현?
    // Layout: 셀을 어떻게 배치?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        collectionView.delegate = self
    }
}

extension StockRankViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return stockList.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StockRankCollectionViewCell", for: indexPath)
        return cell
        // return UICollectionViewCell()
    }
}

extension StockRankViewController: UICollectionViewDelegateFlowLayout {
    }
}

extension StockRankViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // width == collectionView
        return CGSize(width: collectionView.bounds.width, height: 80)
    }
}

StockRankCollectionViewCell code - data update

//
//  StockRankCollectionViewCell.swift
//  StockRank
//
//  Created by sehee on 2022/07/01.
//

import UIKit

class StockRankCollectionViewCell: UICollectionViewCell {
    // uicomponent 연결하자
    // uicomponent에 데이터 업데이트 하는 코드를 넣자
    @IBOutlet weak var rankLabel: UILabel!
    @IBOutlet weak var companyIconImageView: UIImageView!
    @IBOutlet weak var companyNameLabel: UILabel!
    @IBOutlet weak var companyPriceLabel: UILabel!
    @IBOutlet weak var diffLabel: UILabel!
    
    func configure(_ stock: StockModel) {
        rankLabel.text = "\(stock.rank)"
        companyIconImageView.image = UIImage(named: stock.imageName)
        companyNameLabel.text = stock.name
        companyPriceLabel.text = "\(stock.price) 원"
        diffLabel.text = "\(stock.diff)%"
    }
}

StockRankViewController code - data update

//
//  StockRankViewController.swift
//  StockRank
//
//  Created by sehee on 2022/06/30.
//

import UIKit

class StockRankViewController: UIViewController {

    let stockList: [StockModel] = StockModel.list
    @IBOutlet weak var collectionView: UICollectionView!
    
    // Data, Presentation, Layout
    // Data: 어떤 떼이터? - stockList
    // Presentation: 셀을 어떻게 표현?
    // Layout: 셀을 어떻게 배치?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        collectionView.delegate = self
    }
}

extension StockRankViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return stockList.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // guard: as? (꼭 참이어야 하는 조건) else { return (거짓일 경우) } (참일 경우)
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StockRankCollectionViewCell", for: indexPath) as? StockRankCollectionViewCell else {
            return UICollectionViewCell()
        }
        let stock = stockList[indexPath.item]
        cell.configure(stock)
        return cell
    }
}

extension StockRankViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // width == collectionView
        return CGSize(width: collectionView.bounds.width, height: 80)
    }
}

가격 표현(쉼표 추가)

//
//  StockRankCollectionViewCell.swift
//  StockRank
//
//  Created by sehee on 2022/07/01.
//

import UIKit

class StockRankCollectionViewCell: UICollectionViewCell {
    // uicomponent 연결하자
    // uicomponent에 데이터 업데이트 하는 코드를 넣자
    @IBOutlet weak var rankLabel: UILabel!
    @IBOutlet weak var companyIconImageView: UIImageView!
    @IBOutlet weak var companyNameLabel: UILabel!
    @IBOutlet weak var companyPriceLabel: UILabel!
    @IBOutlet weak var diffLabel: UILabel!
    
    func configure(_ stock: StockModel) {
        rankLabel.text = "\(stock.rank)"
        companyIconImageView.image = UIImage(named: stock.imageName)
        companyNameLabel.text = stock.name
        companyPriceLabel.text = "\(convertToCurrencyFormat(price: stock.price)) 원"
        diffLabel.text = "\(stock.diff)%"
    }

    func convertToCurrencyFormat(price: Int) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.maximumFractionDigits = 0
        let result = numberFormatter.string(from: NSNumber(value: price)) ?? ""
        return result
    }
}

(추가) 사용자 UI 반영 - 마이너스일 때 파란색 표시, 플러스일 때는 기본 빨간색 표시

# sol1

        var color: UIColor
        if stock.diff > 0 {
            color = UIColor.systemRed
        } else {
            color = UIColor.systemBlue
        }
        diffLabel.textColor = color

# sol2

        diffLabel.textColor = stock.diff > 0 ? UIColor.systemRed : UIColor.systemBlue

최종 코드

//
//  StockRankViewController.swift
//  StockRank
//
//  Created by sehee on 2022/06/30.
//

import UIKit

class StockRankViewController: UIViewController {

    let stockList: [StockModel] = StockModel.list
    @IBOutlet weak var collectionView: UICollectionView!
    
    // Data, Presentation, Layout
    // Data: 어떤 떼이터? - stockList
    // Presentation: 셀을 어떻게 표현?
    // Layout: 셀을 어떻게 배치?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        collectionView.delegate = self
    }
}

extension StockRankViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return stockList.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // guard: as? (꼭 참이어야 하는 조건) else { return (거짓일 경우) } (참일 경우)
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StockRankCollectionViewCell", for: indexPath) as? StockRankCollectionViewCell else {
            return UICollectionViewCell()
        }
        let stock = stockList[indexPath.item]
        cell.configure(stock)
        return cell
    }
}

extension StockRankViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // width == collectionView
        return CGSize(width: collectionView.bounds.width, height: 80)
    }
}
//
//  StockRankCollectionViewCell.swift
//  StockRank
//
//  Created by sehee on 2022/07/01.
//

import UIKit

class StockRankCollectionViewCell: UICollectionViewCell {
    // uicomponent 연결하자
    // uicomponent에 데이터 업데이트 하는 코드를 넣자
    @IBOutlet weak var rankLabel: UILabel!
    @IBOutlet weak var companyIconImageView: UIImageView!
    @IBOutlet weak var companyNameLabel: UILabel!
    @IBOutlet weak var companyPriceLabel: UILabel!
    @IBOutlet weak var diffLabel: UILabel!
    
    func configure(_ stock: StockModel) {
        rankLabel.text = "\(stock.rank)"
        companyIconImageView.image = UIImage(named: stock.imageName)
        companyNameLabel.text = stock.name
        companyPriceLabel.text = "\(convertToCurrencyFormat(price: stock.price)) 원"
/*        var color: UIColor
        if stock.diff > 0 {
            color = UIColor.systemRed
        } else {
            color = UIColor.systemBlue
        }
        diffLabel.textColor = color
 */
        diffLabel.textColor = stock.diff > 0 ? UIColor.systemRed : UIColor.systemBlue
        diffLabel.text = "\(stock.diff)%"
    }

    func convertToCurrencyFormat(price: Int) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.maximumFractionDigits = 0
        let result = numberFormatter.string(from: NSNumber(value: price)) ?? ""
        return result
    }
}

기본 제공 코드

//
//  StockModel.swift
//  StockRank
//
//  Created by joonwon lee on 2022/04/19.
//

import Foundation

struct StockModel {
    let rank: Int
    let imageName: String
    let name: String
    let price: Int
    let diff: Double
}

extension StockModel {
    static let list: [StockModel] = [
        StockModel(rank: 1, imageName: "TSLA", name: "테슬라", price: 1_238_631, diff: 0.04),
        StockModel(rank: 2, imageName: "AAPL", name: "애플", price: 238_631, diff: 1.04),
        StockModel(rank: 3, imageName: "NFLX", name: "넷플릭스", price: 438_631, diff: -0.04),
        StockModel(rank: 4, imageName: "GOOG", name: "알파벳 A", price: 3_176_631, diff: 0.04),
        StockModel(rank: 5, imageName: "AMZN", name: "아마존", price: 3_538_631, diff: 0.04),
        StockModel(rank: 6, imageName: "NIKE", name: "나이키", price: 158_631, diff: 0.04),
        StockModel(rank: 7, imageName: "DIS", name: "디즈니", price: 138_631, diff: 0.04),
        StockModel(rank: 8, imageName: "TSLA", name: "테슬라", price: 1_238_631, diff: 0.04),
        StockModel(rank: 9, imageName: "AAPL", name: "애플", price: 238_631, diff: 1.04),
        StockModel(rank: 10, imageName: "NFLX", name: "넷플릭스", price: 438_631, diff: -0.04),
        StockModel(rank: 11, imageName: "GOOG", name: "알파벳 A", price: 3_176_631, diff: 0.04),
        StockModel(rank: 12, imageName: "AMZN", name: "아마존", price: 3_538_631, diff: 0.04),
        StockModel(rank: 13, imageName: "NIKE", name: "나이키", price: 158_631, diff: 0.04),
        StockModel(rank: 14, imageName: "DIS", name: "디즈니", price: 138_631, diff: 0.04),
    ]
}

[Next] (4주차) 실습

2022.07.10 - [Dev/Swift] - [Xcode] iOS Swift 앱 개발 Byte Degree - week.04

 

[Xcode] iOS Swift 앱 개발 Byte Degree - week.04

[Review] (3주차) 실습 2022.07.01 - [Swift] - [Xcode] iOS Swift 앱 개발 Byte Degree - week.03 [Xcode] iOS Swift 앱 개발 Byte Degree - week.03 [Review] (2주차) 실습 2022.06.26 - [Swift] - [Xcode] iOS..

sarahee.tistory.com

 

728x90
728x90

+ Recent posts