• 원하는 영역에 ScrollView와 StackView를 구현한다.

  • StackView에 뷰를 3개 넣는다. (preView, currentView, nextView)

  • 초기엔 currentView를 보게끔 ‘self.scrollView.setContentOffset’를 설정해준다.

self.scrollView.setContentOffset(CGPoint(x: width, y: 0), animated: false)
  • 데이터가 총 max개 있다고 가정할때 현재 StackView에 있는 데이터는 { preView: max-1, currentView: 0 (현재 보고있는 곳) , nextView: 1 } 이렇게 된다. 다음 화면으로 넘기게 되면 currentView를 보고 있는데 nextView를 보게 된다. { preView: max-1, currentView: 0, nextView: 1 (현재 보고있는 곳) } 이 시점을 인식하여 다시 currentView를 보게 하고 데이터를 하나씩 옆으로 밀어준다. ( preView: 0, currentView: 1 (현재 보고있는 곳) , nextView: 2 ) 이전 화면으로 넘기는 경우도 동일하다.
private var currentIndex: Int = 0

private func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.x == width * 2 {
        self.nextIndex()
        self.setSubview(by: self.currentIndex)
        scrollView.setContentOffset(CGPoint(x: width, y: 0), animated: false)
    }
    if scrollView.contentOffset.x == 0 {
        self.preIndex()
        self.setSubview(by: self.currentIndex)
        scrollView.setContentOffset(CGPoint(x: width, y: 0), animated: false)
    }
}

// StackView에 있는 subview의 데이터를 변경해주는 함수
private func setSubview(by index: Int) {
    self.subViews[0].set(by: self.store(by: index - 1))
    self.subViews[1].set(by: self.store(by: index))
    self.subViews[2].set(by: self.store(by: index + 1))
}

// 데이터 범위를 넘는 오류에 대한 처리 (index 변경)
private func nextIndex() {
    var index = self.currentIndex + count
    if index >= self.storage.numberOfItem {
        index -= self.storage.numberOfItem
    }
    self.currentIndex = index
}

private func preIndex() {
    var index = self.currentIndex - count
    if index < 0 {
        index += self.storage.numberOfItem
    }
    self.currentIndex = index
}

  • 그 외 사용된 코드들
private let scrollView: UIScrollView = {
    let scrollview = UIScrollView()
    scrollview.showsVerticalScrollIndicator = false
    scrollview.showsHorizontalScrollIndicator = false
    scrollview.isPagingEnabled = true
    scrollview.clipsToBounds = false
    scrollview.contentInset = UIEdgeInsets(top: 0, left: -16.0, bottom: 0, right: -16.0)
    return scrollview
}()

private let stackView: UIStackView = {
    let stackView = UIStackView()
    stackView.axis = NSLayoutConstraint.Axis.horizontal
    stackView.distribution = UIStackView.Distribution.fill
    stackView.alignment = UIStackView.Alignment.center
    stackView.spacing = 0.0
    return stackView
}()

private let subViews: [StoreBestListViewCell] = {
    var subViews = [StoreBestListViewCell]()
    for _ in 0..<3 {
        subViews.append(StoreBestListViewCell())
    }
    return subViews
}()

override func setupViews() {
    self.addSubview(self.scrollView)
    self.scrollView.addSubview(self.stackView)
    self.addSubview(self.allButton)
}

override func setupConstraints() {
    self.scrollView.snp.makeConstraints { (make) in
    	make.top.equalTo(self.titleLabel.snp.bottom).offset(24.0)
		make.left.equalToSuperview().offset(16.0)
		make.right.equalToSuperview().offset(-16.0)
	 	make.height.equalTo(height)
    }

	self.stackView.snp.makeConstraints { (make) in
		make.left.right.bottom.top.equalToSuperview()
	}
}

func set(by group: CustomGroupForm) {
    self.storage = GroupStorage(group: group)
    self.addStackSubviews()
    if self.storage.numberOfItem > 1 {
        self.scrollView.setContentOffset(CGPoint(x: width * 2, y: 0), animated: false)
    }
}

private func addStackSubviews() {
    for subview in self.subViews {
        self.stackView.addArrangedSubview(subview)
        subview.snp.makeConstraints { (make) in
            make.height.equalTo(height)
            make.width.equalTo(UIApplication.screenWidth()-32.0)
        }
    }
    self.currentIndex = 0
    self.setSubview(by: self.currentIndex)
}