UIScrollView와 UIPageControl을 이용한 페이지 전환
UI설정
ViewController에 UIScrollView와 PageControl을 올린 후 ScrollView의 레이아웃을 Top, Bottom, Left, Right 모두 safeArea와 0으로 맞춥니다.
ScrollView와 Page Control는 따로 위치하도록 있어야 합니다.
ViewController와 연결
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var pageControl: UIPageControl!
Page 설정
우선 page를 설정하기 위해 변경할 페이지가 들어갈 UIView 배열 선언해줍니다.
var pages: [UIView] = []
그다음 여러 UIView를 만들어 배경색을 설정해준 후에 위에서 만든 pages 배열에 추가해주었습니다.
func setupPages() {
let page1 = UIView()
page1.backgroundColor = .black
let page2 = UIView()
page2.backgroundColor = .gray
let page3 = UIView()
page3.backgroundColor = .lightGray
pages = [page1, page2, page3]
}
ScrollView 설정
scrollViewDidScroll 함수를 사용하기 위해 UIScrollViewDelegate 프로토콜 채택하여주고!
class ViewController: UIViewController, UIScrollViewDelegate { }
ScrollView의 프레임을 설정하는 함수를 만들어줍니다.
func configueScrollView() {
scrollView.delegate = self
scrollView.isPagingEnabled = true
scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(pages.count),
height: scrollView.frame.height)
for (index, page) in pages.enumerated() {
page.frame = CGRect(x: view.frame.width * CGFloat(index),
y: 0,
width: view.frame.width,
height: scrollView.frame.height)
scrollView.addSubview(page)
}
}
scrollView.delegate
: scrollViewDelegate를 사용하기 위한 설정scrollView.isPagingEnabled = true
: 스크롤 뷰 내에서의 페이징 활성화- 스크롤 뷰를 움직일 때, 스크롤 뷰의 내용이 페이지의 경계에서 멈추도록 함.
scrollView.contentSize = CGSize(width: 너비설정, height: 높이설정)
: 스크롤 뷰 내의 content 사이즈 설정- 보여지는 contentSize가 아닌 실제 Content가 차지하고 있는 View의 프레임 설정
- 너비는 현재 view의 너비의 페이지의 개수를 곱한 값
- 높이는 현재 scrollView의 높이와 동일하게 설정
page.frame = CGRect(x: x 좌표의 위치, y: y 좌표의 위치, width: 너비 설정, height: 높이 설정)
: 각 page의 프레임 사이즈 설정- x축은 각 프레임 크기의 곱셈 예를 들어, 300이 프레임의 너비라면 0번째 페이지는 0, 1번째 페이지는 300, 2번째 페이지는 600의 x축 위치를 가짐.
- y축은 고정이기 때문에 모든 프레임의 위치가 0으로 고정
- 너비는 현재 view의 너비
- 높이는 scrollView의 높이와 동일하게 설정함으로써 스크롤이 옆으로 움직이도록 설정
scrollView.addSubview(page)
: scrollView의 ContentView에 page들을 올림
scrollView가 scroll 되었을 때 실행되는 함수인 scrollViewDidScroll에 pageControl의 현재 페이지 번호를 설정합니다.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x / view.frame.width)
pageControl.currentPage = Int(pageIndex)
}
let pageIndex = round(scrollView.contentOffset.x / view.frame.width)
: 스크롤의 위치에 따른 현재 위치한 페이지 인덱스 계산하는 변수
- scrollView.contentOffset.x 가 현재 수평 스크롤의 위치를 나타내어 스크롤 뷰의 왼쪽 가장자리부터 현재 위치의 시작점 까지의 거리를 표시함. 이를 frame의 너비로 나누면 현재 페이지의 인덱스가 나옴. 예를 들어, frame 너비가 300이라고 하고 현재 스크롤의 위치가 400이라고 하면 400/300의 반올림 값은 1이므로 현재 페이지가 1임을 알 수 있음
pageControl.currentPage = Int(pageIndex)
: 현재 페이지의 인덱스번호를 가지고 pageControl의 현재 페이지 위치를 나타냄.
pageControl의 초기설정
pageControl.numberOfPages = pages.count
pageControl.currentPage = 0
pageControl.numberOfPages = pages.count
: pageControl의 페이지 갯수 설정pageControl.currentPage = 0
: pageControl이 표시하는 현재 페이지 설정
전체 코드
class ViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var pageControl: UIPageControl!
var pages: [UIView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setupPages()
configueScrollView()
pageControl.numberOfPages = pages.count
pageControl.currentPage = 0
}
func setupPages() {
let page1 = UIView()
page1.backgroundColor = .black
let page2 = UIView()
page2.backgroundColor = .gray
let page3 = UIView()
page3.backgroundColor = .lightGray
pages = [page1, page2, page3]
}
func configueScrollView() {
scrollView.delegate = self
scrollView.isPagingEnabled = true
scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(pages.count),
height: scrollView.frame.height)
for (index, page) in pages.enumerated() {
page.frame = CGRect(x: view.frame.width * CGFloat(index),
y: 0,
width: view.frame.width,
height: scrollView.frame.height)
scrollView.addSubview(page)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x / view.frame.width)
pageControl.currentPage = Int(pageIndex)
}
}
실행화면