기어가더라도 제대로

[UIKit-기초] Xib에서 코드로 UIView 파일을 불러오기 본문

UIKit 기초

[UIKit-기초] Xib에서 코드로 UIView 파일을 불러오기

Damagucci-juice 2025. 1. 26. 15:03

개념 이해

  • 스토리 보드: Xcode에서 UI 요소가 보여지도록 보이는 창
    • UIViewController들의 네비게이션 흐름, UI의 선언, 코드가 아닌 사람이 보기에 편리하게 적용, 피그마의 한 페이지와 대치
  • 장점: UI 흐름을 한 눈에 볼 수 있다. 네비게이션 흐름도 정의가 되어있어서 그런 점은 편리
  • 단점: 스토리보드로 작업을 하게 되면 협업하기가 어렵다. 예를들어 화면의 좌표를 이동하는 등의 사소한 일을 해도 어떻게 변했는지 리뷰어가 어떤 작업을 했는지 알기 어려움

  • Nib: Next Interface Builder, 예전 UI를 그리는 도구
  • Xib: Xcode Interface Builder, 기능상으로 nib과 차이가 없음
    • UIView요소를 커스텀한 컴포넌트로 구성한 객체로, 예를 들어 UIView에 UILabel을 선언해서 재사용한다던가 하는 방식이다. 피그마의 한 컴포넌트를 생각하면 좋다. 

특징: *.storyboard 파일과 *.xib 파일은 서로 다르다. 쉽게 생각하면 하나의 컴포넌트와 1:1 연결이 됨

장점: 재사용되는 요소를 정의해서 그 때 그 때 사용하기 편리

단점: 마찬가지로 협업할 때 어렵고, 코드로 수정이 가능한 세세한 기능을 전부 적용하기는 어렵다. 

Xib 파일을 생성

프로젝트를 생성한다. Interface를 Storyboard로 선언

프로젝트 생성

 

  • View UI를 생성

  • MyCustomView.xib 파일이 생성

  • 기본으로 생성하면 노치 부분이 표시 되는데, 전체 화면을 그리는 것보다 작은 UIView 요소를 그릴 거기 때문에 사이즈를 FreeForm으로 편집하면 노치가 사라짐

  • FreeForm을 설정했기 때문에 요소를 자유롭게 드래그해서 사이즈를 변경하고, Safe Area Relative Margins를 체크 해제

Safe Area Relative Margins: 뷰 안에서도 Safe Area를 생각해서 마진을 설정하겠느냐는 건데, 큰 화면이면 몰라도 UIView요소에서 그것까지 고려하면 낭비라 생각해서 해제

  • UILabel을 하나 추가하고 레이아웃을 화면에 꽉 차게 지정

  • 기준을 Safe Area가 아닌 SuperView를 기준으로 지정

  • 레이블의 글자와 백그라운드 색상을 지정

 

  • 코드로 MyCustomView.swift를 생성하고 MyCustomView.xib 파일과 연결

 

  • init 코드를 선언: xib 파일을 코드에서 인식할 수 있도록 불러오는 작업이 필요함
import UIKit

class MyCustomView: UIView {
    @IBOutlet weak var someLabel: UILabel!

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

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupXib()
    }

    func setupXib() {
        
    }
}
  • nib 을 불러오는 함수를 확장해서 선언
extension UIView {
    func loadViewFromNib(nib: String) -> UIView? {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nib, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }
}
  • setupXib에서 이 메소드를 호출해서 구현 
func setupXib() {
    guard let view = loadViewFromNib(nib: "MyCustomView") else { return }
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
}
  • 만약 Auto Layout을 이용해서 구현한다고 하면, Autoresizing Mask를 사용하도록 설정

func setupXib() {
    guard let view = loadViewFromNib(nib: "MyCustomView") else { return }
    view.translatesAutoresizingMaskIntoConstraints = false
    addSubview(view)
    NSLayoutConstraint.activate([
        leadingAnchor.constraint(equalTo: view.leadingAnchor),
        trailingAnchor.constraint(equalTo: view.trailingAnchor),
        bottomAnchor.constraint(equalTo: view.bottomAnchor),
        topAnchor.constraint(equalTo: view.topAnchor),
    ])
}

 

UIViewController에 .Xib를 이식

  • UIView를 뷰컨트롤러에서 추가

  • MyCustomView로 선언

  • 전체 뷰컨트롤러에서 Auto layout 지정하고 MyCustomView 의 크기가 정해지지 않았으므로, Intrinsic Size에서 Place Holder로 지정

 

  • 완료 모습

 

전체 코드

https://github.com/Damagucci-Juice/ExXib

 

GitHub - Damagucci-Juice/ExXib

Contribute to Damagucci-Juice/ExXib development by creating an account on GitHub.

github.com

 

Comments