VesselWheel

Code로 쓰는 UI와 StroyBoard 로 쓰는 UI의 장점과 단점(from. 권영호 튜터) 본문

Xcode Study

Code로 쓰는 UI와 StroyBoard 로 쓰는 UI의 장점과 단점(from. 권영호 튜터)

JasonYang 2024. 1. 4. 15:36

UIKit

Code로 쓰는 UI

장점

  1. 유지보수 용이성: 코드로 UI를 작성하면 코드의 버전 관리 및 수정이 용이하며, 코드베이스를 유지 비용이 적습니다. Git과 같은 버전 관리 도구를 활용하여 협업 시 코드 변경을 효과적으로 관리할 수 있습니다.
  2. 동적인 UI 작성: 코드로 UI를 구성하면 런타임에 동적으로 UI를 변경하거나 조작하기 용이하며, 복잡한 UI 로직을 더 쉽게 구현할 수 있습니다. (버튼에 따른 UI 이동 등을 구현하기 용이합니다.)
  3. 분업 용이성: 개발자가 각자의 역할(디자인 구현, 비즈니스 로직 구현 등)에 집중할 수 있으며, 작업 분담이 용이합니다.

단점

  1. 시각화 어려움: UI의 구성 요소를 코드로 작성하면 디자인을 미리 시각적으로 확인하기 어렵습니다. 디자이너가 실시간으로 디자인을 확인하기 어려울 수 있습니다.
  2. 학습 곡선: 코드로 UI를 작성하는 데는 시간이 걸리며, 초기에는 Storyboard보다 학습 곡선이 높을 수 있습니다.

Storyboard로 만드는 UI

장점

  1. 시각적 디자인: Storyboard를 사용하면 시각적으로 UI를 디자인하고 미리보기할 수 있어 디자인 프로세스를 편리하게 관리할 수 있습니다.
  2. 시각적 피드백: 인터페이스를 시각적으로 확인하면서 개발자와 디자이너 간의 협업이 원활해집니다.
  3. 빠른 프로토타이핑: 빠른 프로토타이핑이 가능하며, 초기 단계에서 빠르게 UI를 만들어 볼 수 있습니다.

단점

  1. 버전 관리 어려움: Storyboard 파일의 변경 사항을 정확하게 추적하고 관리하기 어려울 수 있습니다.
  2. 협업 어려움: 큰 프로젝트에서 Storyboard를 사용하면 충돌이 발생할 수 있고, 협업이 어려울 수 있습니다. 큰 프로젝트에서 Storyboard 파일이 커지면 충돌이 발생할 수 있고, 병합이 어려워질 수 있습니다.
  3. 복잡한 UI 관리 어려움: 복잡한 UI를 구성할 경우 Storyboard 파일이 커지면서 관리가 어려워질 수 있습니다.

 

터치 이벤트 처리하기

코드로 UI를 작성한 경우 - 터치 이벤트 처리 예시

import UIKit

class CodeViewController: UIViewController {

    let button: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Tap me!", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }

    func setupUI() {
        view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }

    @objc func buttonTapped() {
        print("Button tapped!")
        // 여기에 터치 이벤트에 대한 추가 로직을 작성할 수 있습니다.
    }
}

Storyboard를 사용하는 경우에는 인터페이스 빌더에서 액션을 추가하여 터치 이벤트를 처리할 수 있습니다. 아래는 Storyboard에서 버튼을 추가하고 터치 이벤트를 처리하는 방법입니다.

  1. Storyboard에서 뷰 컨트롤러에 버튼을 추가합니다.
  2. Control 키를 누른 상태에서 버튼을 뷰 컨트롤러에 드래그하여 액션 메서드를 연결합니다.
  3. 액션 메서드의 이름을 지정하고, 이 메서드에서 터치 이벤트를 처리할 코드를 추가합니다.

 

Storyboard에 추가된 버튼에 대한 Swift 코드 예시

  1. Storyboard에서 뷰 컨트롤러에 버튼을 추가합니다.
  2. Control 키를 누른 상태에서 버튼을 뷰 컨트롤러에 드래그하여 액션 메서드를 연결합니다.
  3. 액션 메서드의 이름을 지정하고, 이 메서드에서 터치 이벤트를 생성할 수 있다. 
import UIKit

class StoryboardViewController: UIViewController {

    @IBAction func buttonTapped(_ sender: UIButton) {
        print("Button tapped!")
        // 여기에 터치 이벤트에 대한 추가 로직을 작성할 수 있습니다.
    }
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        let vc = MyCollectionViewController()
        window?.rootViewController = vc
        window?.makeKeyAndVisible()
    }

 

delegate, datasource 형태

class ItemCollectionViewCell: UICollectionViewCell {
    // UICollectionViewCell에 표시될 내용을 나타내는 뷰나 레이블 등을 추가할 수 있습니다.
    var titleLabel: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)

        // 셀 내부에 라벨 추가
        titleLabel = UILabel(frame: contentView.bounds)
        titleLabel.textAlignment = .center
        titleLabel.textColor = .black
        contentView.addSubview(titleLabel)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class MyCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    var collectionView: UICollectionView!
    var items: [String] = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // UICollectionViewFlowLayout을 사용하여 그리드 형태의 레이아웃 생성
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.minimumInteritemSpacing = 10
        layout.minimumLineSpacing = 10

        // UICollectionView 생성 및 레이아웃 설정
        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
        collectionView.backgroundColor = .white

        // UICollectionViewDelegate 및 UICollectionViewDataSource 설정
        collectionView.delegate = self
        collectionView.dataSource = self

        // 셀 등록
        collectionView.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: "ItemCell")

        // UICollectionView를 뷰에 추가
        view.addSubview(collectionView)
    }

    // MARK: - UICollectionViewDataSource

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ItemCell", for: indexPath) as! ItemCollectionViewCell
        cell.titleLabel.text = items[indexPath.item]
        return cell
    }

    // MARK: - UICollectionViewDelegateFlowLayout

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // 셀의 크기를 설정합니다.
        let cellWidth = (collectionView.bounds.width - 30) / 2  // 예시로 한 줄에 2개씩 표시
        let cellHeight = 50
        return CGSize(width: cellWidth, height: CGFloat(cellHeight))
    }
}

https://teamsparta.notion.site/455b24eb655a4e12955ee3be675f1134