구현 결과

구현 코드 - https://github.com/ryr0121/UIKitPractice/tree/main/TableViewPracticeWithStoryboard

 

구현 과정

1. Storyboard에 TableView 추가

컴포넌트 추가 단축키 - cmd + shift + L

 

2. 추가한 TableView를 @IBOutlet으로 연결

 

3. TableView에 사용할 TableViewCell을 xib파일로 정의

   (1) xib 파일 생성하기

새 파일 생성 단축키 - cmd + N
"Also create XIB file"을 반드시 체크!!!해주어야만 .xib이 생성됨
생성 완.

 

   (2) xib 파일 내에 컴포넌트 추가 및 레이아웃 구성

파일 듀얼로 띄우는 법 - option을 누른 채로 옆에 띄울 파일을 클릭

 

4. TableView를 사용하기 위한 사전 작업을 포함한 코드 추가 (프로토콜 채택, 커스텀 셀 등록 등)

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()커

        setupTableView()
    }
    
    func setupTableView() {
        // TableView를 사용하기 위해 필수적인 프로토콜 채택
        tableView.delegate = self
        tableView.dataSource = self
        // TableView에 커스텀 셀을 사용하기 위한 사전 등록
        tableView.register(UINib(nibName: "MainTableViewCell", bundle: nil), forCellReuseIdentifier: "MainTableViewCell")
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setupTableView()
    }
    
    func setupTableView() {
        // TableView를 사용하기 위해 필수적인 프로토콜 채택
        tableView.delegate = self
        tableView.dataSource = self
        // TableView에 커스텀 셀을 사용하기 위한 사전 등록
        tableView.register(UINib(nibName: "MainTableViewCell", bundle: nil), forCellReuseIdentifier: "MainTableViewCell")
    }
}

결과물

사용 라이브러리 - SnapKit , Then

구현 코드 - https://github.com/ryr0121/UIKitPractice/tree/main/DoubleCVPractice

 

포함 관계

노란색 배경 CollectionView > 파란색 배경 CollectionView > 초록색 배경 View (Cell)

 

구현 과정

1. ViewController안에 노란색 배경의 CollectionView 정의

class ViewController: UIViewController {
	...
	var collectionView: UICollectionView!

	func setupCollectionView() {
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: .init()).then{
            let flowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize(width: self.view.frame.width, height: 100)
            flowLayout.scrollDirection = .vertical
            flowLayout.minimumLineSpacing = 10

            $0.collectionViewLayout = flowLayout
            $0.delegate = self
            $0.dataSource = self
            $0.backgroundColor = .yellow

            $0.showsHorizontalScrollIndicator = false

            $0.decelerationRate = .fast
            $0.isPagingEnabled = false

            $0.register(MainCollectionViewCell.self, forCellWithReuseIdentifier: MainCollectionViewCell.identifier)
        }
	}
	...
}

 

2. ViewController 내에서 CollectionView 관련 프로토콜을 채택하며 cellForItemAt 메소드 내에 새롭게 정의한 CollectionViewCell을 반환시킴

extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainCollectionViewCell.identifier, for: indexPath) as? MainCollectionViewCell else { return UICollectionViewCell() }
        return cell
    }
}

 

3. 위에서 반환되는 셀(파란색 배경)을 정의하는 CollectionViewCell 클래스 내에서 해당 클래스에 또 다른 CollectionView를 가지도록 정의 및 프로토콜 채택

class MainCollectionViewCell: UICollectionViewCell {
    ...    
    var subCollectionView: UICollectionView!

    func setupCollectionView() {
        subCollectionView = UICollectionView(frame: .zero, collectionViewLayout: .init()).then{
            let flowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize(width: 100, height: 100)
            flowLayout.scrollDirection = .horizontal
            flowLayout.minimumLineSpacing = 10

            $0.collectionViewLayout = flowLayout
            $0.delegate = self
            $0.dataSource = self
            $0.backgroundColor = .systemBlue

            $0.showsHorizontalScrollIndicator = false

            $0.decelerationRate = .fast
            $0.isPagingEnabled = false

            $0.register(SubCollectionViewCell.self, forCellWithReuseIdentifier: SubCollectionViewCell.identifier)
        }
    }
    ...
}

extension MainCollectionViewCell: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SubCollectionViewCell.identifier, for: indexPath) as? SubCollectionViewCell else { return UICollectionViewCell() }
        return cell
    }
}

 

4. 파란색 배경의 셀이 가지는 CollectionView의 셀을 정의하는 클래스(초록색 아이템)를 정의

class SubCollectionViewCell: UICollectionViewCell {
    static let identifier = "SubCollectionViewCell"

    var containerView = UIView().then { $0.backgroundColor = .green }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.contentView.addSubview(containerView)
        
        containerView.snp.makeConstraints { make in
            make.top.leading.bottom.trailing.equalToSuperview().inset(5)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

 

 

새로운 플러터 프로젝트에 여러 플러그인을 사용하기 위해 dependency를 수정하면서, 불가피하게 flutter upgrade를 한 후에 위의 오류를 겪음

M1 맥에서 해당 오류가 자주 나타나는 것 같아서, 대부분의 서치 결과로 나온 아래의 명령어를 입력한 후, Podfile 내의 일부분을 주석처리 하여 해결함

 

sudo arch -x86_64 gem install ffi
sudo arch -x86_64 gem install cocoapods
arch -x86_64 pod install	// 이 부분에서 아래 이미지의 오류가 남, Podfile 수정을 통해 해결 가능

위 이미지의 오류가 난다면 Podfile 내에서 아래와 같이 Runner 내에 RunnerTests에 관한 부분을 주석처리 해준 후 다시 명령어를 입력해주면 해결 가능함

Podfile 수정
Podfile 수정 후 다시 install 하니 잘 됨

 

컬렉션 뷰 셀 내에 세부 내용을 보여줄 라벨과 날짜를 보여줄 라벨 두 가지를 추가하고

날짜 라벨은 날짜 딱 한 줄만 보여주도록, 내용 라벨은 여러줄에 걸쳐 보여줄 수 있도록 제약조건 설정을 해주었다 (각각 모두 12로 맞춰줌)

이 때 hugging priority 관련의 제약조건 오류가 생기는데, Content Hugging Priority가 두 라벨 모두 같은 값이고, 셀 내의 제약조건에 따라 요소들을 위치시키려고 하자니, 어떤 요소를 더 늘려서 맞춰넣어야 하는지 애매해져버려 발생하는 오류인 것 같다

 

Content Hugging Priority값이 더 낮으면, 그 값이 더 높은 요소 대신에 크기가 늘려져서 제약조건에 맞도록 설정된다

값이 더 높은 요소는 정해진 조건값에 따라 그 크기를 유지할 수 있게 된다

 

 

내용 라벨의 Content Hugging Priority 값을 1 낮추어서, 날짜 라벨의 그 값보다 더 낮도록 설정해주면 아래와 같이 오류가 해결된다

 

 


content compression resistance priority는 요소가 가지는 크기가 커지는 경우에 대해, 찌그러질 것이냐 말것이냐에 대한 우선순위를 정하는 것이다

이미지에서의 컬렉션뷰 셀과 같이 정해진 범위내에서 만약 내용 라벨에 담길 컨텐츠가 많아지면, 내용 라벨이 자신의 크기를 줄이던지, 혹은 날짜 라벨이 줄어들던지 해야할 것이다

이 경우에 대해, content compression resistance priority값이 날짜 라벨이 더 높게 설정된다면 날짜 라벨은 크기를 유지하고, 값이 더 낮은 내용 라벨이 찌그러지게(크기가 줄어들게) 되는 것이다

 


 

일단 내가 이해한 바로는,,,

Content Hugging Priority

       -> 자리 남는다; 누가 몸집 더 키울래? (값 높은 애 : 전 아닙니다 / 값 낮은 애 : 아휴 제가 늘릴게요;)

Content Compression Resistance Priority
      -> 뭐야 자리 부족하잖아; 누가 찌그러질래? (값 높은 애 : 전 아니라고요 / 값 낮은 애 : 예예 저요)

+ Recent posts