728x90
반응형
테이블뷰의 헤더에 다양한 커스텀 뷰를 추가해본 적이 있을 것이다.
ScrollView + PageControl로 이미지 슬라이더를 구현했던 적이 있는데, 전체 뷰의 스크롤을 하단으로 내림에 따라 해당 헤더뷰가 화면에서 사리지게 되고, 다시 올라왔을 때 하나의 문제를 발견할 수 있었다...
예를 들어 이미지 슬라이더의 이미지를 3번째까지 슬라이드 해두고, 뷰를 끝까지 내린 후 다시 헤더로 왔을 때 아이템이 0번째로 이동해있는 문제였다...
이유를 찾아보니...
viewForHeaderInSection은 단 한 번 호출되는 것이 아니라 여러 번 호출된다는 것 때문이었다!
(여러 번의 조건 = "헤더뷰"가 등장할 때 마다)
즉 이를 고려해서 코드를 구현했어야 했는데, 매번 헤더가 등장할 때 마다 해당 메서드가 호출되는지 몰랐었다.
기존 방식
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
for index in 0..<images.count {
let imageView = UIImageView()
let xPos = headerWidth * CGFloat(index)
imageView.frame = CGRect(x: xPos, y: 0, width: scrollView.bounds.width, height: scrollView.bounds.height)
imageView.image = UIImage(named: images[index])
scrollView.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
// 뷰의 전체 크기를 그 때 그 때 정해줌
scrollView.contentSize.width = scrollView.frame.width * CGFloat(index + 1)
}
}
헤더뷰가 호출될 때 마다 이미지와 페이지 컨트롤의 위치가 0으로 올 수 밖에 없는 코드다.
개선안
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// 이미지만 먼저 추가
for index in 0..<images.count {
let imageView = UIImageView()
let xPos = headerWidth * CGFloat(index)
imageView.frame = CGRect(x: xPos, y: 0, width: scrollView.bounds.width, height: scrollView.bounds.height)
imageView.image = UIImage(named: images[index])
scrollView.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
// 뷰의 전체 크기는 미리 정해둠
scrollView.contentSize.width = scrollView.frame.width * CGFloat(images.count)
}
스크롤뷰의 전체 x 너비를 미리 구하여 고정시켜두고, 이미지는 별도로 추가해둔다면 현재(CurrentPage)에도 변화를 주지 않고, 기존에 선택했던 이미지와 그 위치를 보여주게 된다!
이번에 배운 것은... viewForHeaderInSection은 보여질 때 마다 매번 새롭게 호출된다는 것.
끄읕
728x90
반응형