👨🏻‍💻iOS 공부/iOS & Swift

[iOS] viewForHeaderInSection의 주기에 대하여...

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
반응형