UIPageViewController, UIPageControl을 이용해서 위의 화면과 같은 온보딩 화면을 만들려고 한다.
이 온보딩 화면은 3가지 방법으로 페이지 이동이 가능하다.
- 스와이프를 이용한 페이지 이동
- 페이지 컨트롤 이용한 페이지 이동
- 다음 버튼을 이용한 페이지 이동
1. 온보딩 화면을 만들 뷰컨트롤러에 Container View를 추가하고 컨테이너뷰를 추가하면서 생긴 뷰 컨트롤러를 삭제해 준다.
컨테이너뷰를 추가하면 왼쪽 사진처럼 컨테이너뷰에 연결된 뷰컨트롤러 하나가 같이 생성된다. 같이 생성된 뷰 컨트롤러를 삭제해 주면 된다. 삭제하고 나면 오른쪽 사진처럼 컨테이너뷰만 남게 된다.
2. UIPageViewController를 추가해 준 후 control을 눌러서 컨테이너뷰에서 페이지 뷰컨트롤러로 연결시켜 준 후 Embed를 선택해 준다.
3. UIPageControl을 원하는 위치에 추가해 준다.
뷰컨트롤러에 아웃렛도 설정해 준다.
4. 온보딩 화면에 들어갈 페이지들의 뷰 컨트롤러들을 추가해 준다.
페이지 뷰 컨트롤러에서 스토리보드아이디를 사용해야 하기 때문에 각 뷰컨트롤러에 스토리보드아이디를 설정해 준다.
5. 그럼 이제 페이지 뷰 컨트롤러 설정부터 해주겠다.
우선 온보드페이지뷰컨트롤러 파일을 생성하여 스토리보드의 온보드페이지 뷰컨트롤러와 연결해 준다.
6. 페이지뷰컨트롤러에 온보딩 뷰컨트롤러 리스트를 생성해 준다.
UIStoryBoardsms 온보딩 화면이 있는 스토리보드의 이름을 넣어서 가져올 수 있도록 한다.
withIdentifi는 위에서 설정해 준 각 화면의 스토리보드아이디를 넣어준다.
setViewControllers를 통해 리스트의 맨 처음 뷰컨트롤러를 보여주도록 설정해 준다.
import UIKit
class OnboardPageViewController: UIPageViewController {
var contentPageViewControllerList = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
contentPageViewControllerList = [
storyBoard.instantiateViewController(withIdentifier: "OneOnboard"),
storyBoard.instantiateViewController(withIdentifier: "TwoOnboard"),
storyBoard.instantiateViewController(withIdentifier: "ThreeOnboard"),
storyBoard.instantiateViewController(withIdentifier: "FourOnboard"),
storyBoard.instantiateViewController(withIdentifier: "FiveOnboard")
]
setViewControllers([contentPageViewControllerList[0]], direction: .forward, animated: false, completion: nil)
}
}
7. 이제 페이지 뷰 컨트롤러의 datasource와 delegate를 설정해 준다.
- 7-1 데이터소스 설정
viewControllerBefore
- 이전 화면으로 스와이프 하면 이전 화면으로 어떤 뷰를 보여줄지 결정해 주는 데이터소스
viewControllerAfter
- 다음화면으로 스와이프하면 다음화면으로 어떤 뷰를 보여줄지 결정해주는 데이터 소스
extension OnboardPageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = contentPageViewControllerList.firstIndex(of: viewController)!
if currentIndex == 0 {
return nil
} else {
return contentPageViewControllerList[currentIndex - 1]
}
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = contentPageViewControllerList.firstIndex(of: viewController)!
if currentIndex == contentPageViewControllerList.count - 1 {
return nil
} else {
return contentPageViewControllerList[currentIndex + 1]
}
}
}
- 7-2 델리게이트 설정
didFinishAnimating 페이지 이동 움직임이 끝났을 때 실행해 줄 것을 설정해 주는 것이다.
여기서는 페이지 이동이 끝났을 때 페이지 컨트롤도 이동된 위치의 인덱스를 표현해 주도록 설정해 준다.
뒤에서 다시 걸정 해주겠다.
extension TutorialPageViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
}
}
- 7-3 goToPage 함수 추가
데이터소스 델리게이트 외에도
우리는 페이지컨트롤을 이용해서도 페이지 이동이 가능해야 하기 때문에
페이지 컨트롤이 있는 뷰컨트롤러에서도 페이지뷰컨트롤러의 페이지를 이동시킬 수 있도록 goToPage라는 함수 하나를 추가해 준다.
import UIKit
class OnboardPageViewController: UIPageViewController {
var contentPageViewControllerList = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
contentPageViewControllerList = [
storyBoard.instantiateViewController(withIdentifier: "OneOnboard"),
storyBoard.instantiateViewController(withIdentifier: "TwoOnboard"),
storyBoard.instantiateViewController(withIdentifier: "ThreeOnboard"),
storyBoard.instantiateViewController(withIdentifier: "FourOnboard"),
storyBoard.instantiateViewController(withIdentifier: "FiveOnboard")
]
setViewControllers([contentPageViewControllerList[0]], direction: .forward, animated: false, completion: nil)
}
func goToPage(index: Int) {
let currentViewController = viewControllers!.first!
let currentViewControllerIndex = contentPageViewControllerList.firstIndex(of: currentViewController)!
let direction: NavigationDirection = index > currentViewControllerIndex ? .forward : .reverse
setViewControllers([contentPageViewControllerList[index]], direction: direction, animated: false, completion: nil)
}
}
다음에 이어서!
'iOS' 카테고리의 다른 글
[ iOS / Swift ] XCode 스토리보드 컬렉션뷰 구현 ( CollectionView ) (0) | 2023.09.15 |
---|---|
[ iOS / Swift ] XCode 프로젝트에 폰트(Custom Font) 추가하는 방법 (0) | 2023.09.14 |
[swift] Struct and Class (0) | 2023.07.31 |
[Swift] Closure (0) | 2023.07.29 |
[Swift] Collection - Set (0) | 2023.07.28 |