Lv 1 화면 구성
1-1 파일 및 디렉토리 분리
우선 기획에 맞게 대략적인 프로젝트의 파일과 폴더를 생성하였다.
1-2 SceneDelegate 에서 탭바 생성
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let tabBarVC = UITabBarController()
let vc1 = SearchTapViewController()
let vc2 = SavedTapViewController()
vc1.title = "검색 탭"
vc2.title = "담은 책 리스트 탭"
tabBarVC.setViewControllers([vc1, vc2], animated: false)
tabBarVC.modalPresentationStyle = .fullScreen
window?.rootViewController = tabBarVC
window?.makeKeyAndVisible()
}
필요한 탭이 두개이고 그에 맞게 뷰컨트롤러 두개를
SceneDelegate 에서 탭바를 생성한 뒤 설정해 주었다.
1-3 검색 탭 UI 구현
검색 탭에는 서치바와 컬렉션뷰 (최근검색, 검색결과) 가 들어간다.
SearchTapView 에 서치바와 컬렉션뷰를 구현하였다.
컬렉션뷰는 CompositionalLayout을 사용하였다.
FlowLayout VS CompositionalLayout
컬렉션뷰의 레이아웃은 두가지가 있다.
FlowLayout: 일렬로 깔끔하게 줄 맞춰 정렬하는 자동 정리 도구, 단순한 구현에 쉽다.
CompositionalLayout: 다양한 크기의 박스들을 조합해서 원하는 형태를 만드는 레고, 복잡한 레이아웃 구현을 간단하게 할 수 있다.
이번 프로젝트에서는 컬렉션뷰에 다른 모양의 두가지 섹션을 구현할 예정이므로
각각에 맞는 복잡한 레이아웃 구현에 더 적합한 CompositionalLayout 을 사용해보기로 하였다.
컬렉션뷰의 구성
컬렉션 뷰는 위와같이 섹션>그룹>아이템 으로 구성되어있다.
lazy var searchCollectionView: UICollectionView = {
let layout = createCompositionalLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(SearchListCell.self, forCellWithReuseIdentifier: SearchListCell.id)
collectionView.register(SectionHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: SectionHeader.id)
collectionView.backgroundColor = .white
return collectionView
}()
컬렉션뷰 생성 클로저에서 layout을 섹션에 맞게 생성해주는 메서드를 활용하여
sectionIndex에 따라 다른 모양의 섹션을 만들 수 있도록 구현하였다.
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
switch sectionIndex {
case 0:
return nil
case 1:
return self.createSearchListSection()
default:
return nil
}
}
}
아직은 섹션 0 이 필요 없기 때문에 nil 로 리턴하게 두어 표시되지 않도록 해보았다.
/// 검색결과섹션 레이아웃
private func createSearchListSection() -> NSCollectionLayoutSection {
// 아이템 크기
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(60)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// 그룹 크기
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(60)
)
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
// 아이템 사이의 간격
group.interItemSpacing = .fixed(16)
group.contentInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16)
// 섹션
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 10
section.contentInsets = .init(top: 10, leading: 10, bottom: 10, trailing: 10)
// 헤더 추가
let headerSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(30)
)
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerSize,
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [header]
return section
}
섹션으로 리턴해주는 createSearchListSection 메서드 안에서 컬렉션뷰의 레이아웃을 설정해줄 수 있다.
아이템, 그룹, 섹션에 대한 크기 설정을 각각 해줄 수 있다.
.fractionalWidth : 화면 비율로 크기 설정
.absolute : 값을 직접 주어 설정
그룹, 섹션
group.interItemSpacing = .fixed : 아이템 사이의 간격 설정
.contentInsets : 인셋 설정
section.interGroupSpacing = 10 : 그룹의 spacing 설정
섹션 헤더 설정
섹션에는 헤더, 푸터 가 있다. 위 아래에 들어가는 title 같은 것
이 프로젝트에서는 헤더만 사용하기 때문에 헤더의 크기도 설정해주어야 한다.
헤더뷰
- 섹션의 헤더, 푸터는 UICollectionReusableView 을 상속하여 생성 후
UICollectionViewDataSource 에서 적용해주어야 한다.
class SectionHeader: UICollectionReusableView {
static let id = "SectionHeader"
let label: UILabel = {
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 24)
label.textColor = .black
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureUI() {
addSubview(label)
label.snp.makeConstraints { make in
make.leading.equalToSuperview().inset(10)
}
}
}
서치바를 추가한 모습
서치바와 컬렉션뷰 탭바가 잘 적용된 모습이다.
컬렉션 뷰 레이아웃 참고
https://hackmd.io/@8J6ycQ90Qne5m_5VeNQWBA/rJCNBBGNa
CollectionView - FlowLayout vs CompositionalLayout - HackMD
<h1><center> CollectionView - FlowLayout vs CompositionalLayout </center></h1> ###### title: `Colle
hackmd.io
https://velog.io/@ddophi98/Compositional-Layout
Compositional Layout
Compositional Layout에 대해 정리한 내용입니다
velog.io
'내일배움캠프 iOS' 카테고리의 다른 글
UIKit) TIL # 53 앱개발 심화주차 개인과제 - Lv3 상세화면, 담은 책 목록, CoreData (0) | 2025.01.03 |
---|---|
UIKit) TIL # 52 앱개발 심화주차 개인과제 - Lv 2 API 연결 (0) | 2025.01.02 |
UIKit) TIL # 50 앱개발 심화주차 개인과제 - 기획 (0) | 2024.12.30 |
UIKit) TIL # 49 넷플릭스 클론 강의 (1) | 2024.12.27 |
UIKit) TIL # 48 넷플릭스 클론 강의 (0) | 2024.12.26 |