UIScrollView Infinite Paging
by Seoyeong
-
원하는 영역에 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)
}
Subscribe via RSS