오늘은 새로운 과제를 바로 시작해보자.
모두 코드를 사용해 구현해보기로 해서 이번에는 SnapKit을 적극적으로 한번 사용해 볼 예정이다. SPM을 통해 SnapKit을 넣어주고 이제 코드로 컴포넌트를 생성하고 레이아웃을 잡아보자!
TapbarController 생성
우선 두개의 탭을 가진 앱을 만들 예정이니 먼저 탭바를 넣어주자 탭바는 SceneDelegate에 구성할 예정이다. 탭바에 넣어 둘 VC를 미리 2개 만들어 두고 이름을 설정한다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: windowScene)
let tabBarVC = UITabBarController()
let firstVC = SearchViewController()
firstVC.tabBarItem = UITabBarItem(title: "책 검색", image: UIImage(systemName: "book"), tag: 0)
let secondVC = MyPageViewController()
secondVC.tabBarItem = UITabBarItem(title: "마이페이지", image: UIImage(systemName: "person.circle"), tag: 1)
tabBarVC.viewControllers = [firstVC, secondVC]
tabBarVC.tabBar.backgroundColor = .systemGray5
self.window?.rootViewController = tabBarVC
window?.makeKeyAndVisible()
}
그 다음 탭바 컨트롤러를 생성해 tabBarVC에 넣어준 후 첫 번째 두 번째 VC를 이전에 만들어둔 VC와 연결할 수 있도록 인스턴스에 담아둔다.
그 이후 탭바 아이콘과 탭명을 설정하고
tabBarVC.viewControllers = [firstVC, secondVC]
이렇게 탭바 뷰컨트롤러즈에 VC를 배열로 넣어주면 탭바는 완성된다.
앱을 빌드했을때 바로 탭바 먼저 호출될 수 있도록 rootViewController를 연결한다.
Compositional Layout 을 활용한 컬렉션 뷰 구현
이제 첫번째 VC에는 책 목록과 최근 본 책을 확인할 수 있도록 각각 컬렉션 뷰를 구성할 예정이다.
먼저 클로저를 활용해 컴포넌트들을 생성해주었다.
let searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: nil)
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "원하는 책을 검색해주세요."
return searchController
}()
var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.showsVerticalScrollIndicator = false
return scrollView
}()
var recentlyLabel: UILabel = {
let label = UILabel()
label.text = "최근 본 책"
label.textAlignment = .left
return label
}()
var bookLabel:UILabel = {
let label = UILabel()
label.text = "BOOK"
label.textAlignment = .left
return label
}()
사용할 컴포넌트들을 이렇게 선언한 후 이제 컬렉션 뷰를 만들어줄 예정인데, 이번에는 저번에 사용해봤던 Compositional Layout을 사용해볼 생각이다.
var recentlyCollectionView: UICollectionView = {
let layout = UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .absolute(150))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(150))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 5
return section
}
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(RecentlyViewedCollectionViewCell.self, forCellWithReuseIdentifier: "RecentlyCollectionViewCell")
collectionView.backgroundColor = .blue
return collectionView
}()
var bookCollectinView: UICollectionView = {
let layout = UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(100))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(100))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 10
return section
}
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(BookCollectionViewCell.self, forCellWithReuseIdentifier: "BookCollectionViewCell")
collectionView.backgroundColor = .gray
return collectionView
}()
첫번째 컬렉션 뷰는 가로로 한줄로 구성된 컬렉션 뷰를 만들 예정이고,
두번째 컬렉션 뷰는 세로로 스와이프가 가능한 컬렉션 뷰를 생성해 볼 예정이다.
var recentlyCollectionView: UICollectionView = {
let layout = UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
// 각 아이템의 크기 설정
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .absolute(150))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)
// 그룹 크기 설정
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(150))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
// 섹션 설정
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 5
return section
}
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(RecentlyViewedCollectionViewCell.self, forCellWithReuseIdentifier: "RecentlyCollectionViewCell")
collectionView.backgroundColor = .blue
return collectionView
}()
각각 아이템, 그룹, 섹션을 설정한 뒤 값을 알맞게 넣으면 원하는 만큼 섹션이 나눠져 구성할 수 있다.
CompositionalLayout은 다음 페이지에 조금 더 자세하게 다뤄 볼 예정이다.
SnapKit을 사용해 오토레이아웃 잡기
이번 과제는 코드로 모든 내용을 작성해 볼 예정이기에 오토레이아웃을 조금 더 직관적이고 편리하게 구성할 수 있는 SnapKit을 사용했다.
func setupLayout() {
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
contentView.snp.makeConstraints {
$0.edges.width.equalToSuperview()
}
searchController.searchBar.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(10)
$0.leading.trailing.equalToSuperview().inset(10)
}
recentlyLabel.snp.makeConstraints {
$0.top.equalTo(searchController.searchBar.snp.bottom).offset(10)
$0.leading.trailing.equalToSuperview().offset(10)
}
recentlyCollectionView.snp.makeConstraints {
$0.top.equalTo(recentlyLabel.snp.bottom).offset(10)
$0.leading.trailing.equalToSuperview().inset(5)
$0.height.equalTo(150)
}
bookLabel.snp.makeConstraints {
$0.top.equalTo(recentlyCollectionView.snp.bottom).offset(10)
$0.leading.trailing.equalToSuperview().inset(5)
}
bookCollectinView.snp.makeConstraints {
$0.top.equalTo(bookLabel.snp.bottom).offset(10)
$0.leading.trailing.equalToSuperview().inset(5)
$0.height.equalTo(700)
}
}
스냅킷을 사용하지 않고 오토레이아웃을 잡았다면 지금보다 훨씬 더 긴 코드들과 앵커들이 난무하는 코드가 됐었겠지만 스냅킷을 사용하니 이렇게 직관적이고 깔끔한 코드베이스 오토레이아웃이 가능하다 🙂
top.leading.trailing.bottom 이런식으로 같은 값을 넣을때 한줄에 모든 값을 다 넣을 수 있다는 점과 offset, inset을 활용해 더 직관적이고 편리하게 오토레이아웃을 구성할 수 있다는 점이 너무 좋았다.
이번 과제에 적극적으로 사용해 스냅킷을 완벽 숙달할 수 있도록 하자!
이렇게 각각 컴포넌트들과 오토레이아웃을 설정했으면 이렇게 구현이 완료된다 🙂
내일은 컴포지셔널 레이아웃을 다시 손보고 각 컬렉션 뷰에 셀을 올린 뒤 데이터 모델링을 해서 카카오 API 책 검색 데이터를 가져와 띄워 볼 예정이다.
'◽️ Programming > T I L' 카테고리의 다른 글
책 검색 앱 만들기 (3) (0) | 2024.05.03 |
---|---|
책 검색 앱 만들기 (2) (3) | 2024.05.01 |
[ProJect 일지] 영화 예매 앱 만들기 (5) (2) | 2024.04.27 |
[ProJect 일지] 영화 예매 앱 만들기 (4) (0) | 2024.04.25 |
[ProJect 일지] 영화 예매 앱 만들기 (3) (0) | 2024.04.24 |