깃허브
https://github.com/bryjna07/BookSearchApp
과제 안내 및 기획
https://yjuni22.tistory.com/71
구현 TIL
Lv 1 ~ 2
https://yjuni22.tistory.com/72
Lv 2
https://yjuni22.tistory.com/73
Lv 3
https://yjuni22.tistory.com/74
트러블 슈팅
문제 : 검색기능이 제대로 되지 않음
- 서치 버튼 클릭 시 Nan error 와 함께 검색기능이 실행되지 않음
해결과정:
해당 에러 서칭
https://stackoverflow.com/questions/67757790/how-to-handle-nan-not-a-number-in-swift-correctly
How to handle NaN (Not a number) in Swift correctly?
I have a function that calculates the width of the cells for me based on a CollectionView. This layout is dynamic. In the simulator I repeated the case that the width / height of the CollectionView...
stackoverflow.com
어떤 에러인지는 모르겠으나 일단 검색기능이 되지 않기에 관련 구현 코드들을 다시 천천히 살펴보았다.
위의 stackoverflow 에서 보니 API 로 받아오는 데이터를 count 로 셀을 그려주고 있는데
UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 0
} else {
return bookArrays.count
}
}
이 부분에서 count 에서 (Nan, or not-a-number) 의 에러가 발생하는 건가? 싶어서 확인중
모델의 데이터를 옵셔널로 하지 않은 것이 확인되어 이게 문제인가? 하고 바꾸었다.
하지만 알고보니 시뮬레이터에서 마우스로 돋보기를 클릭했을 때 발생하는 오류였다.
결과:
에러에 관련된 내용은 아니지만
API 모델을 받아오는 경우 없는 데이터도 있을 수 있기 때문에
옵셔널로 처리해 주는 것이 좋다는 것을 리마인드할 수 있었다.
트러블 슈팅 #2, Lv 4
문제
최근검색 섹션을 처음에 보이지 않도록 하는 방법에 대한 고민
뷰와 뷰컨트롤러가 분리되어 있는 구조에서, SearchTapView(뷰)에서 recentBookArrays(뷰컨트롤러의 데이터)에 접근하기 어려운 상황 발생
최근검색 섹션을 구현하기 전
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
switch sectionIndex {
case 0:
return nil
case 1:
return self.createSearchListSection()
default:
return nil
}
}
이미 최근 검색 섹션을 생성하기 전에 대략적인 구조를 구현해두었기 때문에
이를 활용하고 싶었다.
해결과정:
뷰와 뷰컨트롤러 사이의 데이터를 주고받기 위해 클로저를 활용
SearchTapView에 "최근 검색 데이터의 개수"를 반환하는 클로저(recentBooksCountHandler)를 추가하여 문제 해결
SearchTapView
final class SearchTapView: UIView {
// 최근 본 책 숫자 넘겨받는 클로저
var recentBooksCountHandler: (() -> Int)?
SearchTapViewController
class SearchTapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 최근검색 섹션이 없을 때 관련
searchTapView.recentBooksCountHandler = { [weak self] in
return self?.recentBookArrays.count ?? 0
}
SearchTapView 의 레이아웃 메서드
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
switch sectionIndex {
case 0:
// 최근 본 책 0이면 nil 반환
if let count = self.recentBooksCountHandler?(), count == 0 {
return nil
}
return self.createRecentBooksSection()
case 1:
return self.createSearchListSection()
default:
return nil
}
}
결과:
최근 검색 데이터(recentBookArrays)가 없을 때, count가 0 일때
즉 처음 진입 시 "최근 검색" 섹션이 나타나지 않게 되었다.
이런 부분이 MVC의 단점이지 않을까 .. ?
Lv 4 최근검색 섹션 구현
RecentBooksCell 을 새로 생성하여
cellForItemAt 에 섹션 0 일때 해당 셀의 모양으로 나오도록 구현하였다.
// 섹션별 셀 데이터
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RecentBooksCell.id, for: indexPath) as! RecentBooksCell
cell.titleLabel.text = recentBookArrays[indexPath.row].title
// 셀 색상 배열 정의
let colors: [UIColor] = [
.systemRed, .systemOrange, .systemYellow, .systemGreen,
.systemBlue, .systemMint, .systemPink , .systemPurple,
.systemBrown, .systemGray2
]
let colorIndex = indexPath.row % colors.count
cell.imageView.backgroundColor = colors[colorIndex]
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SearchListCell.id, for: indexPath) as! SearchListCell
cell.bookNameLabel.text = bookArrays[indexPath.row].title
cell.authorNameLabel.text = bookArrays[indexPath.row].authors?.first
cell.bookPriceLabel.text = "\(bookArrays[indexPath.row].price ?? 0)원"
cell.layer.borderWidth = 2
return cell
}
}
색깔을 넣고 싶어서 색상 배열을 만들고 인덱스에 따라 색상이 적용되도록 하였다.
didSet을 활용해 셀 클릭 시 최근 본 책이 생기도록 구현하였다.
var recentBookArrays: [Document] = []
var recentBooks: Document? {
didSet {
configureWithRecentBooks()
}
}
// didSelectItemAt 누르면 recentBooks 에서 didSet 실행
private func configureWithRecentBooks() {
guard let book = self.recentBooks else { return }
self.recentBookArrays.insert(book, at: 0)
if self.recentBookArrays.count > 10 {
self.recentBookArrays.removeLast()
}
self.searchTapView.searchCollectionView.reloadData()
}
배열의 맨 앞으로 들어가도록 insert, at: 0 을 활용하고
10개가 넘어가면 마지막 것을 지우도록 했다.
'내일배움캠프 iOS' 카테고리의 다른 글
iOS) TIL # 56 심화주차 팀프로젝트 - 2 (0) | 2025.01.08 |
---|---|
iOS) TIL # 55 심화주차 팀프로젝트 - 1 (0) | 2025.01.07 |
UIKit) TIL # 53 앱개발 심화주차 개인과제 - Lv3 상세화면, 담은 책 목록, CoreData (0) | 2025.01.03 |
UIKit) TIL # 52 앱개발 심화주차 개인과제 - Lv 2 API 연결 (0) | 2025.01.02 |
UIKit) TIL # 51 앱개발 심화주차 개인과제 - Lv 1,2 컬렉션뷰 CompositinalLayout (0) | 2024.12.31 |